diff --git a/lib/cretonne/meta/gen_instr.py b/lib/cretonne/meta/gen_instr.py index 28db9e81d2..ab42b01850 100644 --- a/lib/cretonne/meta/gen_instr.py +++ b/lib/cretonne/meta/gen_instr.py @@ -103,6 +103,38 @@ def gen_arguments_method(fmt, is_mut): .format(n, capture, arg)) +def gen_instruction_data(fmt): + # type: (srcgen.Formatter) -> None + """ + Generate the InstructionData enum. + + Every variant must contain `opcode` and `ty` fields. An instruction that + doesn't produce a value should have its `ty` field set to `VOID`. The size + of `InstructionData` should be kept at 16 bytes on 64-bit architectures. If + more space is needed to represent an instruction, use a `Box` to + store the additional information out of line. + """ + + fmt.line('#[derive(Clone, Debug, Hash, PartialEq, Eq)]') + fmt.line('#[allow(missing_docs)]') + with fmt.indented('pub enum InstructionData {', '}'): + for f in InstructionFormat.all_formats: + with fmt.indented('{} {{'.format(f.name), '},'): + fmt.line('opcode: Opcode,') + if f.typevar_operand is None: + pass + elif f.has_value_list: + fmt.line('args: ValueList,') + elif f.num_value_operands == 1: + fmt.line('arg: Value,') + else: + fmt.line('args: [Value; {}],'.format(f.num_value_operands)) + for field in f.imm_fields: + fmt.line( + '{}: {},' + .format(field.member, field.kind.rust_type)) + + def gen_instruction_data_impl(fmt): # type: (srcgen.Formatter) -> None """ @@ -682,6 +714,8 @@ def generate(isas, out_dir): # opcodes.rs fmt = srcgen.Formatter() gen_formats(fmt) + gen_instruction_data(fmt) + fmt.line() gen_instruction_data_impl(fmt) fmt.line() instrs = gen_opcodes(groups, fmt) diff --git a/lib/cretonne/src/ir/instructions.rs b/lib/cretonne/src/ir/instructions.rs index 2d462064d1..358c63d942 100644 --- a/lib/cretonne/src/ir/instructions.rs +++ b/lib/cretonne/src/ir/instructions.rs @@ -11,11 +11,9 @@ use std::str::FromStr; use std::ops::{Deref, DerefMut}; use ir; -use ir::{Value, Type, Ebb, JumpTable, SigRef, FuncRef, StackSlot, MemFlags}; -use ir::immediates::{Imm64, Uimm8, Uimm32, Ieee32, Ieee64, Offset32}; -use ir::condcodes::*; +use ir::{Value, Type, Ebb, JumpTable, SigRef, FuncRef}; use ir::types; -use isa::RegUnit; +use isa; use entity; use bitset::BitSet; @@ -94,190 +92,6 @@ impl FromStr for Opcode { } } -/// Contents on an instruction. -/// -/// Every variant must contain `opcode` and `ty` fields. An instruction that doesn't produce a -/// value should have its `ty` field set to `VOID`. The size of `InstructionData` should be kept at -/// 16 bytes on 64-bit architectures. If more space is needed to represent an instruction, use a -/// `Box` to store the additional information out of line. -#[derive(Clone, Debug, Hash, PartialEq, Eq)] -#[allow(missing_docs)] -pub enum InstructionData { - Unary { opcode: Opcode, arg: Value }, - UnaryImm { opcode: Opcode, imm: Imm64 }, - UnaryIeee32 { opcode: Opcode, imm: Ieee32 }, - UnaryIeee64 { opcode: Opcode, imm: Ieee64 }, - UnaryBool { opcode: Opcode, imm: bool }, - UnaryGlobalVar { - opcode: Opcode, - global_var: ir::GlobalVar, - }, - Binary { opcode: Opcode, args: [Value; 2] }, - BinaryImm { - opcode: Opcode, - arg: Value, - imm: Imm64, - }, - Ternary { opcode: Opcode, args: [Value; 3] }, - MultiAry { opcode: Opcode, args: ValueList }, - NullAry { opcode: Opcode }, - InsertLane { - opcode: Opcode, - lane: Uimm8, - args: [Value; 2], - }, - ExtractLane { - opcode: Opcode, - lane: Uimm8, - arg: Value, - }, - IntCompare { - opcode: Opcode, - cond: IntCC, - args: [Value; 2], - }, - IntCompareImm { - opcode: Opcode, - cond: IntCC, - arg: Value, - imm: Imm64, - }, - IntCond { - opcode: Opcode, - cond: IntCC, - arg: Value, - }, - FloatCompare { - opcode: Opcode, - cond: FloatCC, - args: [Value; 2], - }, - FloatCond { - opcode: Opcode, - cond: FloatCC, - arg: Value, - }, - IntSelect { - opcode: Opcode, - cond: IntCC, - args: [Value; 3], - }, - Jump { - opcode: Opcode, - destination: Ebb, - args: ValueList, - }, - Branch { - opcode: Opcode, - destination: Ebb, - args: ValueList, - }, - BranchIcmp { - opcode: Opcode, - cond: IntCC, - destination: Ebb, - args: ValueList, - }, - BranchInt { - opcode: Opcode, - cond: IntCC, - destination: Ebb, - args: ValueList, - }, - BranchFloat { - opcode: Opcode, - cond: FloatCC, - destination: Ebb, - args: ValueList, - }, - BranchTable { - opcode: Opcode, - arg: Value, - table: JumpTable, - }, - Call { - opcode: Opcode, - func_ref: FuncRef, - args: ValueList, - }, - IndirectCall { - opcode: Opcode, - sig_ref: SigRef, - args: ValueList, - }, - FuncAddr { opcode: Opcode, func_ref: FuncRef }, - StackLoad { - opcode: Opcode, - stack_slot: StackSlot, - offset: Offset32, - }, - StackStore { - opcode: Opcode, - arg: Value, - stack_slot: StackSlot, - offset: Offset32, - }, - HeapAddr { - opcode: Opcode, - heap: ir::Heap, - arg: Value, - imm: Uimm32, - }, - Load { - opcode: Opcode, - flags: MemFlags, - arg: Value, - offset: Offset32, - }, - Store { - opcode: Opcode, - flags: MemFlags, - args: [Value; 2], - offset: Offset32, - }, - RegMove { - opcode: Opcode, - arg: Value, - src: RegUnit, - dst: RegUnit, - }, - CopySpecial { - opcode: Opcode, - src: RegUnit, - dst: RegUnit, - }, - RegSpill { - opcode: Opcode, - arg: Value, - src: RegUnit, - dst: StackSlot, - }, - RegFill { - opcode: Opcode, - arg: Value, - src: StackSlot, - dst: RegUnit, - }, - Trap { opcode: Opcode, code: ir::TrapCode }, - CondTrap { - opcode: Opcode, - arg: Value, - code: ir::TrapCode, - }, - IntCondTrap { - opcode: Opcode, - cond: IntCC, - arg: Value, - code: ir::TrapCode, - }, - FloatCondTrap { - opcode: Opcode, - cond: FloatCC, - arg: Value, - code: ir::TrapCode, - }, -} - /// A variable list of `Value` operands used for function call arguments and passing arguments to /// basic blocks. #[derive(Clone, Debug)]