X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FARM%2FARMInstrThumb.td;h=786dd65b8742155381113e293fd0b8ee00cbd64c;hb=cb721da4c64bb9a844cf5180647dc926a5fd5f24;hp=64142ad24bd65f961fb732581eac5300a0ef4762;hpb=c6f7b27fdab506bc15d6e5f356adf1e455d1d571;p=oota-llvm.git diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index 64142ad24bd..786dd65b874 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -120,7 +120,10 @@ def t_addrmode_sp : Operand, // Miscellaneous Instructions. // -let Defs = [SP], Uses = [SP] in { +// FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE +// from removing one half of the matched pairs. That breaks PEI, which assumes +// these will always be in pairs, and asserts if it finds otherwise. Better way? +let Defs = [SP], Uses = [SP], hasSideEffects = 1 in { def tADJCALLSTACKUP : PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2), NoItinerary, "@ tADJCALLSTACKUP $amt1", @@ -132,6 +135,55 @@ PseudoInst<(outs), (ins i32imm:$amt), NoItinerary, [(ARMcallseq_start imm:$amt)]>, Requires<[IsThumb1Only]>; } +def tNOP : T1pI<(outs), (ins), NoItinerary, "nop", "", + [/* For disassembly only; pattern left blank */]>, + T1Encoding<0b101111> { + let Inst{9-8} = 0b11; + let Inst{7-0} = 0b00000000; +} + +def tYIELD : T1pI<(outs), (ins), NoItinerary, "yield", "", + [/* For disassembly only; pattern left blank */]>, + T1Encoding<0b101111> { + let Inst{9-8} = 0b11; + let Inst{7-0} = 0b00010000; +} + +def tWFE : T1pI<(outs), (ins), NoItinerary, "wfe", "", + [/* For disassembly only; pattern left blank */]>, + T1Encoding<0b101111> { + let Inst{9-8} = 0b11; + let Inst{7-0} = 0b00100000; +} + +def tWFI : T1pI<(outs), (ins), NoItinerary, "wfi", "", + [/* For disassembly only; pattern left blank */]>, + T1Encoding<0b101111> { + let Inst{9-8} = 0b11; + let Inst{7-0} = 0b00110000; +} + +def tSEV : T1pI<(outs), (ins), NoItinerary, "sev", "", + [/* For disassembly only; pattern left blank */]>, + T1Encoding<0b101111> { + let Inst{9-8} = 0b11; + let Inst{7-0} = 0b01000000; +} + +def tSETENDBE : T1I<(outs), (ins), NoItinerary, "setend\tbe", + [/* For disassembly only; pattern left blank */]>, + T1Encoding<0b101101> { + let Inst{9-5} = 0b10010; + let Inst{3} = 1; +} + +def tSETENDLE : T1I<(outs), (ins), NoItinerary, "setend\tle", + [/* For disassembly only; pattern left blank */]>, + T1Encoding<0b101101> { + let Inst{9-5} = 0b10010; + let Inst{3} = 0; +} + // The i32imm operand $val can be used by a debugger to store more information // about the breakpoint. def tBKPT : T1I<(outs), (ins i32imm:$val), NoItinerary, "bkpt\t$val", @@ -140,6 +192,19 @@ def tBKPT : T1I<(outs), (ins i32imm:$val), NoItinerary, "bkpt\t$val", let Inst{9-8} = 0b10; } +// Change Processor State is a system instruction -- for disassembly only. +// The singleton $opt operand contains the following information: +// opt{4-0} = mode ==> don't care +// opt{5} = changemode ==> 0 (false for 16-bit Thumb instr) +// opt{8-6} = AIF from Inst{2-0} +// opt{10-9} = 1:imod from Inst{4} with 0b10 as enable and 0b11 as disable +// +// The opt{4-0} and opt{5} sub-fields are to accommodate 32-bit Thumb and ARM +// CPS which has more options. +def tCPS : T1I<(outs), (ins i32imm:$opt), NoItinerary, "cps${opt:cps}", + [/* For disassembly only; pattern left blank */]>, + T1Misc<0b0110011>; + // For both thumb1 and thumb2. let isNotDuplicable = 1 in def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), IIC_iALUr, @@ -208,7 +273,7 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1 in { let Inst{6-3} = 0b1110; // Rm = lr } // Alternative return instruction used by vararg functions. - def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx\t$target", []>, + def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx\t$target",[]>, T1Special<{1,1,0,?}>; // A6.2.3 & A8.6.25 } @@ -236,20 +301,20 @@ let isCall = 1, D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { // Also used for Thumb2 def tBL : TIx2<0b11110, 0b11, 1, - (outs), (ins i32imm:$func, variable_ops), IIC_Br, + (outs), (ins i32imm:$func, variable_ops), IIC_Br, "bl\t${func:call}", [(ARMtcall tglobaladdr:$func)]>, Requires<[IsThumb, IsNotDarwin]>; // ARMv5T and above, also used for Thumb2 def tBLXi : TIx2<0b11110, 0b11, 0, - (outs), (ins i32imm:$func, variable_ops), IIC_Br, + (outs), (ins i32imm:$func, variable_ops), IIC_Br, "blx\t${func:call}", [(ARMcall tglobaladdr:$func)]>, Requires<[IsThumb, HasV5T, IsNotDarwin]>; // Also used for Thumb2 - def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, + def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, "blx\t$func", [(ARMtcall GPR:$func)]>, Requires<[IsThumb, HasV5T, IsNotDarwin]>, @@ -257,7 +322,7 @@ let isCall = 1, // ARMv4T def tBX : TIx2<{?,?,?,?,?}, {?,?}, ?, - (outs), (ins tGPR:$func, variable_ops), IIC_Br, + (outs), (ins tGPR:$func, variable_ops), IIC_Br, "mov\tlr, pc\n\tbx\t$func", [(ARMcall_nolink tGPR:$func)]>, Requires<[IsThumb1Only, IsNotDarwin]>; @@ -271,20 +336,20 @@ let isCall = 1, D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { // Also used for Thumb2 def tBLr9 : TIx2<0b11110, 0b11, 1, - (outs), (ins i32imm:$func, variable_ops), IIC_Br, + (outs), (ins i32imm:$func, variable_ops), IIC_Br, "bl\t${func:call}", [(ARMtcall tglobaladdr:$func)]>, Requires<[IsThumb, IsDarwin]>; // ARMv5T and above, also used for Thumb2 def tBLXi_r9 : TIx2<0b11110, 0b11, 0, - (outs), (ins i32imm:$func, variable_ops), IIC_Br, + (outs), (ins i32imm:$func, variable_ops), IIC_Br, "blx\t${func:call}", [(ARMcall tglobaladdr:$func)]>, Requires<[IsThumb, HasV5T, IsDarwin]>; // Also used for Thumb2 - def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, + def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, "blx\t$func", [(ARMtcall GPR:$func)]>, Requires<[IsThumb, HasV5T, IsDarwin]>, @@ -292,7 +357,7 @@ let isCall = 1, // ARMv4T def tBXr9 : TIx2<{?,?,?,?,?}, {?,?}, ?, - (outs), (ins tGPR:$func, variable_ops), IIC_Br, + (outs), (ins tGPR:$func, variable_ops), IIC_Br, "mov\tlr, pc\n\tbx\t$func", [(ARMcall_nolink tGPR:$func)]>, Requires<[IsThumb1Only, IsDarwin]>; @@ -307,7 +372,7 @@ let isBranch = 1, isTerminator = 1 in { // Far jump let Defs = [LR] in - def tBfar : TIx2<0b11110, 0b11, 1, (outs), (ins brtarget:$target), IIC_Br, + def tBfar : TIx2<0b11110, 0b11, 1, (outs), (ins brtarget:$target), IIC_Br, "bl\t$target\t@ far jump",[]>; def tBR_JTr : T1JTI<(outs), @@ -340,16 +405,34 @@ let isBranch = 1, isTerminator = 1 in { T1Misc<{1,0,?,1,?,?,?}>; } +// A8.6.218 Supervisor Call (Software Interrupt) -- for disassembly only +// A8.6.16 B: Encoding T1 +// If Inst{11-8} == 0b1111 then SEE SVC +let isCall = 1 in { +def tSVC : T1pI<(outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc", []>, + Encoding16 { + let Inst{15-12} = 0b1101; + let Inst{11-8} = 0b1111; +} +} + +// A8.6.16 B: Encoding T1 -- for disassembly only +// If Inst{11-8} == 0b1110 then UNDEFINED +def tTRAP : T1I<(outs), (ins), IIC_Br, "trap", []>, Encoding16 { + let Inst{15-12} = 0b1101; + let Inst{11-8} = 0b1110; +} + //===----------------------------------------------------------------------===// // Load Store Instructions. // -let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in -def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr, +let canFoldAsLoad = 1, isReMaterializable = 1 in +def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr, "ldr", "\t$dst, $addr", [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>, T1LdSt<0b100>; -def tLDRi: T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr, +def tLDRi: T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr, "ldr", "\t$dst, $addr", []>, T1LdSt4Imm<{1,?,?}>; @@ -399,15 +482,14 @@ def tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi, // Load tconstpool // FIXME: Use ldr.n to work around a Darwin assembler bug. -let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in +let canFoldAsLoad = 1, isReMaterializable = 1 in def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, "ldr", ".n\t$dst, $addr", [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>, T1Encoding<{0,1,0,0,1,?}>; // A6.2 & A8.6.59 // Special LDR for loads from non-pc-relative constpools. -let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1, - mayHaveSideEffects = 1 in +let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in def tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, "ldr", "\t$dst, $addr", []>, T1LdStSP<{1,?,?}>; @@ -652,7 +734,7 @@ def tMOVgpr2gpr : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, // multiply register let isCommutable = 1 in def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMUL32, - "mul", "\t$dst, $rhs", + "mul", "\t$dst, $rhs, $dst", /* A8.6.105 MUL Encoding T1 */ [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>, T1DataProcessing<0b1101>; @@ -769,7 +851,7 @@ def tUXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, T1Misc<{0,0,1,0,1,0,?}>; -// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC DAG operation. +// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC operation. // Expanded after instruction selection into a branch sequence. let usesCustomInserter = 1 in // Expanded after instruction selection. def tMOVCCr_pseudo :