From e73583638390bebec9aa6768926db019a13ca0d0 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 13 May 2016 14:27:24 -0700 Subject: [PATCH] Synchronize InstructionFormat and InstructionData. These two enums must have identical variants. One is generated from the instruction formats in meta/cretonne/formats.py, the other defines the contents of an instruction. Emit a conversion from InstructionData to InstructionFormat which also serves to verify the correspondence. Rustc will error is the match is not complete. --- cranelift/src/libcretonne/instructions.rs | 39 ++++++++++++++++++++++- meta/cretonne/__init__.py | 11 +++++++ meta/cretonne/formats.py | 5 ++- meta/gen_instr.py | 14 ++++++++ 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/cranelift/src/libcretonne/instructions.rs b/cranelift/src/libcretonne/instructions.rs index 025e6ebb23..325033284a 100644 --- a/cranelift/src/libcretonne/instructions.rs +++ b/cranelift/src/libcretonne/instructions.rs @@ -108,6 +108,20 @@ pub enum InstructionData { ty: Type, imm: Imm64, }, + UnaryIeee32 { + opcode: Opcode, + ty: Type, + imm: Ieee32, + }, + UnaryIeee64 { + opcode: Opcode, + ty: Type, + imm: Ieee64, + }, + UnaryImmVector { + opcode: Opcode, + ty: Type, // TBD: imm: Box + }, Binary { opcode: Opcode, ty: Type, @@ -117,7 +131,14 @@ pub enum InstructionData { opcode: Opcode, ty: Type, arg: Value, - imm: Imm64, + rhs: Imm64, + }, + // Same as BinaryImm, but the imediate is the lhs operand. + BinaryImmRev { + opcode: Opcode, + ty: Type, + arg: Value, + lhs: Imm64, }, Call { opcode: Opcode, @@ -157,8 +178,12 @@ impl InstructionData { Nullary { opcode, .. } => opcode, Unary { opcode, .. } => opcode, UnaryImm { opcode, .. } => opcode, + UnaryIeee32 { opcode, .. } => opcode, + UnaryIeee64 { opcode, .. } => opcode, + UnaryImmVector { opcode, .. } => opcode, Binary { opcode, .. } => opcode, BinaryImm { opcode, .. } => opcode, + BinaryImmRev { opcode, .. } => opcode, Call { opcode, .. } => opcode, } } @@ -170,8 +195,12 @@ impl InstructionData { Nullary { ty, .. } => ty, Unary { ty, .. } => ty, UnaryImm { ty, .. } => ty, + UnaryIeee32 { ty, .. } => ty, + UnaryIeee64 { ty, .. } => ty, + UnaryImmVector { ty, .. } => ty, Binary { ty, .. } => ty, BinaryImm { ty, .. } => ty, + BinaryImmRev { ty, .. } => ty, Call { ty, .. } => ty, } } @@ -183,8 +212,12 @@ impl InstructionData { Nullary { .. } => None, Unary { .. } => None, UnaryImm { .. } => None, + UnaryIeee32 { .. } => None, + UnaryIeee64 { .. } => None, + UnaryImmVector { .. } => None, Binary { .. } => None, BinaryImm { .. } => None, + BinaryImmRev { .. } => None, Call { ref data, .. } => Some(data.second_result), } } @@ -195,8 +228,12 @@ impl InstructionData { Nullary { .. } => None, Unary { .. } => None, UnaryImm { .. } => None, + UnaryIeee32 { .. } => None, + UnaryIeee64 { .. } => None, + UnaryImmVector { .. } => None, Binary { .. } => None, BinaryImm { .. } => None, + BinaryImmRev { .. } => None, Call { ref mut data, .. } => Some(&mut data.second_result), } } diff --git a/meta/cretonne/__init__.py b/meta/cretonne/__init__.py index 4b8267d2d1..cbad9185fc 100644 --- a/meta/cretonne/__init__.py +++ b/meta/cretonne/__init__.py @@ -55,6 +55,17 @@ value = OperandKind( operand. """) +#: A variable-sizes list of value operands. Use for Ebb and function call +#: arguemnts. +args = OperandKind( + 'args', """ + A variable size list of `value` operands. + + Use this to represent arguemtns passed to a function call, arguments + passed to an extended basic block, or a variable number of results + returned from an instruction. + """) + # Instances of immediate operand types are provided in the cretonne.immediates # module. diff --git a/meta/cretonne/formats.py b/meta/cretonne/formats.py index 6f34214db9..cb02d80998 100644 --- a/meta/cretonne/formats.py +++ b/meta/cretonne/formats.py @@ -7,9 +7,11 @@ in this module. """ -from . import InstructionFormat, value +from . import InstructionFormat, value, args from immediates import imm64, ieee32, ieee64, immvector +Nullary = InstructionFormat() + Unary = InstructionFormat(value) UnaryImm = InstructionFormat(imm64) UnaryIeee32 = InstructionFormat(ieee32) @@ -20,6 +22,7 @@ Binary = InstructionFormat(value, value) BinaryImm = InstructionFormat(value, imm64) BinaryImmRev = InstructionFormat(imm64, value) +Call = InstructionFormat(args, multiple_results=True) # Finally extract the names of global variables in this module. InstructionFormat.extract_names(globals()) diff --git a/meta/gen_instr.py b/meta/gen_instr.py index 8c5ad8a9ce..8fe63cb932 100644 --- a/meta/gen_instr.py +++ b/meta/gen_instr.py @@ -21,6 +21,20 @@ def gen_formats(fmt): fmt.line(f.name + ',') fmt.line() + # Emit a From which also serves to verify that + # InstructionFormat and InstructionData are in sync. + with fmt.indented( + "impl<'a> From<&'a InstructionData> for InstructionFormat {", '}'): + with fmt.indented( + "fn from(inst: &'a InstructionData) -> InstructionFormat {", + '}'): + with fmt.indented('match *inst {', '}'): + for f in cretonne.InstructionFormat.all_formats: + fmt.line(('InstructionData::{} {{ .. }} => ' + + 'InstructionFormat::{},') + .format(f.name, f.name)) + fmt.line() + def collect_instr_groups(targets): seen = set()