1*f4a2713aSLionel Sambuc// This test describes how we eventually want to describe instructions in 2*f4a2713aSLionel Sambuc// the target independent code generators. 3*f4a2713aSLionel Sambuc// RUN: llvm-tblgen %s 4*f4a2713aSLionel Sambuc// XFAIL: vg_leak 5*f4a2713aSLionel Sambuc 6*f4a2713aSLionel Sambuc// Target indep stuff. 7*f4a2713aSLionel Sambucclass Instruction { // Would have other stuff eventually 8*f4a2713aSLionel Sambuc bit isTwoAddress = 0; 9*f4a2713aSLionel Sambuc string AssemblyString; 10*f4a2713aSLionel Sambuc} 11*f4a2713aSLionel Sambucclass RegisterClass; 12*f4a2713aSLionel Sambuc 13*f4a2713aSLionel Sambucclass RTLNode; 14*f4a2713aSLionel Sambuc 15*f4a2713aSLionel Sambucdef ops; // Marker for operand list. 16*f4a2713aSLionel Sambuc 17*f4a2713aSLionel Sambuc// Various expressions used in RTL descriptions. 18*f4a2713aSLionel Sambucdef imm8 : RTLNode; 19*f4a2713aSLionel Sambucdef imm32 : RTLNode; 20*f4a2713aSLionel Sambucdef addr : RTLNode; 21*f4a2713aSLionel Sambuc 22*f4a2713aSLionel Sambucdef set : RTLNode; 23*f4a2713aSLionel Sambucdef signext : RTLNode; 24*f4a2713aSLionel Sambucdef zeroext : RTLNode; 25*f4a2713aSLionel Sambucdef plus : RTLNode; 26*f4a2713aSLionel Sambucdef and : RTLNode; 27*f4a2713aSLionel Sambucdef xor : RTLNode; 28*f4a2713aSLionel Sambucdef shl : RTLNode; 29*f4a2713aSLionel Sambucdef load : RTLNode; 30*f4a2713aSLionel Sambucdef store : RTLNode; 31*f4a2713aSLionel Sambucdef unspec : RTLNode; 32*f4a2713aSLionel Sambuc 33*f4a2713aSLionel Sambuc// Start of X86 specific stuff. 34*f4a2713aSLionel Sambuc 35*f4a2713aSLionel Sambucdef R8 : RegisterClass; 36*f4a2713aSLionel Sambucdef R16 : RegisterClass; 37*f4a2713aSLionel Sambucdef R32 : RegisterClass; 38*f4a2713aSLionel Sambuc 39*f4a2713aSLionel Sambucdef CL; // As are currently defined 40*f4a2713aSLionel Sambucdef AL; 41*f4a2713aSLionel Sambucdef AX; 42*f4a2713aSLionel Sambucdef EDX; 43*f4a2713aSLionel Sambuc 44*f4a2713aSLionel Sambucclass Format<bits<5> val> { 45*f4a2713aSLionel Sambuc bits<5> Value = val; 46*f4a2713aSLionel Sambuc} 47*f4a2713aSLionel Sambuc 48*f4a2713aSLionel Sambucdef Pseudo : Format<0>; def RawFrm : Format<1>; 49*f4a2713aSLionel Sambucdef AddRegFrm : Format<2>; def MRMDestReg : Format<3>; 50*f4a2713aSLionel Sambucdef MRMDestMem : Format<4>; def MRMSrcReg : Format<5>; 51*f4a2713aSLionel Sambucdef MRMSrcMem : Format<6>; 52*f4a2713aSLionel Sambucdef MRM0r : Format<16>; def MRM1r : Format<17>; def MRM2r : Format<18>; 53*f4a2713aSLionel Sambucdef MRM3r : Format<19>; def MRM4r : Format<20>; def MRM5r : Format<21>; 54*f4a2713aSLionel Sambucdef MRM6r : Format<22>; def MRM7r : Format<23>; 55*f4a2713aSLionel Sambucdef MRM0m : Format<24>; def MRM1m : Format<25>; def MRM2m : Format<26>; 56*f4a2713aSLionel Sambucdef MRM3m : Format<27>; def MRM4m : Format<28>; def MRM5m : Format<29>; 57*f4a2713aSLionel Sambucdef MRM6m : Format<30>; def MRM7m : Format<31>; 58*f4a2713aSLionel Sambuc 59*f4a2713aSLionel Sambuc 60*f4a2713aSLionel Sambucclass Inst<dag opnds, string asmstr, bits<8> opcode, 61*f4a2713aSLionel Sambuc Format f, list<dag> rtl> : Instruction { 62*f4a2713aSLionel Sambuc dag Operands = opnds; 63*f4a2713aSLionel Sambuc string AssemblyString = asmstr; 64*f4a2713aSLionel Sambuc bits<8> Opcode = opcode; 65*f4a2713aSLionel Sambuc Format Format = f; 66*f4a2713aSLionel Sambuc list<dag> RTL = rtl; 67*f4a2713aSLionel Sambuc} 68*f4a2713aSLionel Sambuc 69*f4a2713aSLionel Sambuc 70*f4a2713aSLionel Sambuc// Start of instruction definitions, the real point of this file. 71*f4a2713aSLionel Sambuc// 72*f4a2713aSLionel Sambuc// Note that these patterns show a couple of important things: 73*f4a2713aSLionel Sambuc// 1. The order and contents of the operands of the MachineInstr are 74*f4a2713aSLionel Sambuc// described here. Eventually we can do away with this when everything 75*f4a2713aSLionel Sambuc// is generated from the description. 76*f4a2713aSLionel Sambuc// 2. The asm string is captured here, which makes it possible to get rid of 77*f4a2713aSLionel Sambuc// a ton of hacks in the various printers and a bunch of flags. 78*f4a2713aSLionel Sambuc// 3. Target specific properties (e.g. Format) can still be captured as 79*f4a2713aSLionel Sambuc// needed. 80*f4a2713aSLionel Sambuc// 4. We capture the behavior of the instruction with a simplified RTL-like 81*f4a2713aSLionel Sambuc// expression. 82*f4a2713aSLionel Sambuc// 5. The use/def properties for each operand are automatically inferred from 83*f4a2713aSLionel Sambuc// the pattern. 84*f4a2713aSLionel Sambuc// 6. Address expressions should become first-class entities. 85*f4a2713aSLionel Sambuc 86*f4a2713aSLionel Sambuc// Simple copy instruction. 87*f4a2713aSLionel Sambucdef MOV8rr : Inst<(ops R8:$dst, R8:$src), 88*f4a2713aSLionel Sambuc "mov $dst, $src", 0x88, MRMDestReg, 89*f4a2713aSLionel Sambuc [(set R8:$dst, R8:$src)]>; 90*f4a2713aSLionel Sambuc 91*f4a2713aSLionel Sambuc// Simple immediate initialization. 92*f4a2713aSLionel Sambucdef MOV8ri : Inst<(ops R8:$dst, imm8:$src), 93*f4a2713aSLionel Sambuc "mov $dst, $src", 0xB0, AddRegFrm, 94*f4a2713aSLionel Sambuc [(set R8:$dst, imm8:$src)]>; 95*f4a2713aSLionel Sambuc 96*f4a2713aSLionel Sambuc// Two address instructions are described as three-addr instructions, with 97*f4a2713aSLionel Sambuc// the special target-independent isTwoAddress flag set. The asm pattern 98*f4a2713aSLionel Sambuc// should not refer to the $src1, this would be enforced by the 99*f4a2713aSLionel Sambuc// TargetInstrInfo tablegen backend. 100*f4a2713aSLionel Sambuclet isTwoAddress = 1 in 101*f4a2713aSLionel Sambucdef AND8rr : Inst<(ops R8:$dst, R8:$src1, R8:$src2), 102*f4a2713aSLionel Sambuc "and $dst, $src2", 0x20, MRMDestReg, 103*f4a2713aSLionel Sambuc [(set R8:$dst, (and R8:$src1, R8:$src2))]>; 104*f4a2713aSLionel Sambuc 105*f4a2713aSLionel Sambuc// Instructions that have explicit uses/defs make them explicit in the RTL. 106*f4a2713aSLionel Sambuc// Instructions that need extra stuff emitted in the assembly can, trivially. 107*f4a2713aSLionel Sambuclet isTwoAddress = 1 in 108*f4a2713aSLionel Sambucdef SHL32rCL : Inst<(ops R32:$dst, R32:$src), 109*f4a2713aSLionel Sambuc "shl $dst, CL", 0xD2, MRM4r, 110*f4a2713aSLionel Sambuc [(set R32:$dst, (shl R32:$src, CL))]>; 111*f4a2713aSLionel Sambuc 112*f4a2713aSLionel Sambuc// The RTL list is a list, allowing complex instructions to be defined easily. 113*f4a2713aSLionel Sambuc// Temporary 'internal' registers can be used to break instructions apart. 114*f4a2713aSLionel Sambuclet isTwoAddress = 1 in 115*f4a2713aSLionel Sambucdef XOR32mi : Inst<(ops addr:$addr, imm32:$imm), 116*f4a2713aSLionel Sambuc "xor $dst, $src2", 0x81, MRM6m, 117*f4a2713aSLionel Sambuc [(set R32:$tmp1, (load addr:$addr)), 118*f4a2713aSLionel Sambuc (set R32:$tmp2, (xor R32:$tmp1, imm32:$imm)), 119*f4a2713aSLionel Sambuc (store addr:$addr, R32:$tmp2)]>; 120*f4a2713aSLionel Sambuc 121*f4a2713aSLionel Sambuc// Alternatively, if each tmporary register is only used once, the instruction 122*f4a2713aSLionel Sambuc// can just be described in nested form. This would be the canonical 123*f4a2713aSLionel Sambuc// representation the target generator would convert the above into. Pick your 124*f4a2713aSLionel Sambuc// favorite indentation scheme. 125*f4a2713aSLionel Sambuclet isTwoAddress = 1 in 126*f4a2713aSLionel Sambucdef AND32mr : Inst<(ops addr:$addr, R32:$src), 127*f4a2713aSLionel Sambuc "xor $dst, $src2", 0x81, MRM6m, 128*f4a2713aSLionel Sambuc [(store addr:$addr, 129*f4a2713aSLionel Sambuc (and 130*f4a2713aSLionel Sambuc (load addr:$addr), 131*f4a2713aSLionel Sambuc R32:$src) 132*f4a2713aSLionel Sambuc ) 133*f4a2713aSLionel Sambuc ]>; 134*f4a2713aSLionel Sambuc 135*f4a2713aSLionel Sambuc// Describing complex instructions is not too hard! Note how implicit uses/defs 136*f4a2713aSLionel Sambuc// become explicit here. 137*f4a2713aSLionel Sambucdef CBW : Inst<(ops), 138*f4a2713aSLionel Sambuc "cbw", 0x98, RawFrm, 139*f4a2713aSLionel Sambuc [(set AX, (signext AL))]>; 140*f4a2713aSLionel Sambuc 141*f4a2713aSLionel Sambuc// Noop, does nothing. 142*f4a2713aSLionel Sambucdef NOOP : Inst<(ops), "nop", 0x90, RawFrm, []>; 143*f4a2713aSLionel Sambuc 144*f4a2713aSLionel Sambuc 145*f4a2713aSLionel Sambuc// Instructions that don't expect optimization can use unspec. 146*f4a2713aSLionel Sambucdef IN8rr : Inst<(ops), "in AL, EDX", 0xEC, RawFrm, 147*f4a2713aSLionel Sambuc [(set AL, (unspec EDX))]>; 148*f4a2713aSLionel Sambuc 149