X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FARM%2FARMInstrThumb2.td;h=2fedb5398ebc2b2c1c540c0fa408c21cc0159634;hb=c266600bec4b5ba0ee93ffdfeaafcab8f1295145;hp=108a96e4d022c873ece47704412ac1d2c92c7a50;hpb=37474e6d68b42b0d1f4299c8588893bfaa3d0d09;p=oota-llvm.git diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 108a96e4d02..2fedb5398eb 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -127,7 +127,7 @@ def imm0_255_not : PatLeaf<(i32 imm), [{ def t2addrmode_imm12 : Operand, ComplexPattern { let PrintMethod = "printAddrModeImm12Operand"; - string EncoderMethod = "getAddrModeImm12OpValue"; + let EncoderMethod = "getAddrModeImm12OpValue"; let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); } @@ -135,7 +135,7 @@ def t2addrmode_imm12 : Operand, def t2addrmode_imm8 : Operand, ComplexPattern { let PrintMethod = "printT2AddrModeImm8Operand"; - string EncoderMethod = "getT2AddrModeImm8OpValue"; + let EncoderMethod = "getT2AddrModeImm8OpValue"; let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); } @@ -143,13 +143,13 @@ def t2am_imm8_offset : Operand, ComplexPattern { let PrintMethod = "printT2AddrModeImm8OffsetOperand"; - string EncoderMethod = "getT2AddrModeImm8OffsetOpValue"; + let EncoderMethod = "getT2AddrModeImm8OffsetOpValue"; } // t2addrmode_imm8s4 := reg +/- (imm8 << 2) def t2addrmode_imm8s4 : Operand { let PrintMethod = "printT2AddrModeImm8s4Operand"; - string EncoderMethod = "getT2AddrModeImm8s4OpValue"; + let EncoderMethod = "getT2AddrModeImm8s4OpValue"; let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); } @@ -161,7 +161,7 @@ def t2am_imm8s4_offset : Operand { def t2addrmode_so_reg : Operand, ComplexPattern { let PrintMethod = "printT2AddrModeSoRegOperand"; - string EncoderMethod = "getT2AddrModeSORegOpValue"; + let EncoderMethod = "getT2AddrModeSORegOpValue"; let MIOperandInfo = (ops GPR:$base, rGPR:$offsreg, i32imm:$offsimm); } @@ -285,9 +285,13 @@ class T2TwoRegImm { bits<4> Rd; bits<4> Rn; + bits<12> imm; let Inst{11-8} = Rd; - let Inst{3-0} = Rn; + let Inst{19-16} = Rn; + let Inst{26} = imm{11}; + let Inst{14-12} = imm{10-8}; + let Inst{7-0} = imm{7-0}; } class T2sTwoRegImm opcod, string opc, PatFrag opnode> { let Inst{7} = 1; let Inst{5-4} = 0b00; // rotate } - def r_rot : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, i32imm:$rot), IIC_iEXTr, + def r_rot : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, rot_imm:$rot), IIC_iEXTr, opc, ".w\t$Rd, $Rm, ror $rot", [(set rGPR:$Rd, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]> { let Inst{31-27} = 0b11111; @@ -1003,8 +1007,8 @@ multiclass T2I_ext_rrot_uxtb16 opcod, string opc, PatFrag opnode> { let Inst{7} = 1; let Inst{5-4} = 0b00; // rotate } - def r_rot : T2TwoReg<(outs rGPR:$dst), (ins rGPR:$Rm, i32imm:$rot), IIC_iEXTr, - opc, "\t$dst, $Rm, ror $rot", + def r_rot : T2TwoReg<(outs rGPR:$dst), (ins rGPR:$Rm, rot_imm:$rot), + IIC_iEXTr, opc, "\t$dst, $Rm, ror $rot", [(set rGPR:$dst, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]>, Requires<[HasT2ExtractPack, IsThumb2]> { let Inst{31-27} = 0b11111; @@ -1060,7 +1064,8 @@ multiclass T2I_exta_rrot opcod, string opc, PatFrag opnode> { let Inst{7} = 1; let Inst{5-4} = 0b00; // rotate } - def rr_rot : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, i32imm:$rot), + def rr_rot : T2ThreeReg<(outs rGPR:$Rd), + (ins rGPR:$Rn, rGPR:$Rm, rot_imm:$rot), IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, ror $rot", [(set rGPR:$Rd, (opnode rGPR:$Rn, (rotr rGPR:$Rm, rot_imm:$rot)))]>, @@ -1150,73 +1155,63 @@ def t2LEApcrelJT : T2PCOneRegImm<(outs rGPR:$Rd), let Inst{15} = 0; } + +// FIXME: None of these add/sub SP special instructions should be necessary +// at all for thumb2 since they use the same encodings as the generic +// add/sub instructions. In thumb1 we need them since they have dedicated +// encodings. At the least, they should be pseudo instructions. // ADD r, sp, {so_imm|i12} -def t2ADDrSPi : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$sp, t2_so_imm:$imm), - IIC_iALUi, "add", ".w\t$Rd, $sp, $imm", []> { +let isCodeGenOnly = 1 in { +def t2ADDrSPi : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), + IIC_iALUi, "add", ".w\t$Rd, $Rn, $imm", []> { let Inst{31-27} = 0b11110; let Inst{25} = 0; let Inst{24-21} = 0b1000; - let Inst{19-16} = 0b1101; // Rn = sp let Inst{15} = 0; } -def t2ADDrSPi12 : T2I<(outs GPR:$Rd), (ins GPR:$sp, imm0_4095:$imm), - IIC_iALUi, "addw", "\t$Rd, $sp, $imm", []> { - bits<4> Rd; - bits<12> imm; +def t2ADDrSPi12 : T2TwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm), + IIC_iALUi, "addw", "\t$Rd, $Rn, $imm", []> { let Inst{31-27} = 0b11110; - let Inst{26} = imm{11}; let Inst{25-20} = 0b100000; - let Inst{19-16} = 0b1101; // Rn = sp let Inst{15} = 0; - let Inst{14-12} = imm{10-8}; - let Inst{11-8} = Rd; - let Inst{7-0} = imm{7-0}; } // ADD r, sp, so_reg def t2ADDrSPs : T2sTwoRegShiftedReg< - (outs GPR:$Rd), (ins GPR:$sp, t2_so_reg:$ShiftedRm), - IIC_iALUsi, "add", ".w\t$Rd, $sp, $ShiftedRm", []> { + (outs GPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm), + IIC_iALUsi, "add", ".w\t$Rd, $Rn, $ShiftedRm", []> { let Inst{31-27} = 0b11101; let Inst{26-25} = 0b01; let Inst{24-21} = 0b1000; - let Inst{19-16} = 0b1101; // Rn = sp let Inst{15} = 0; } // SUB r, sp, {so_imm|i12} -def t2SUBrSPi : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$sp, t2_so_imm:$imm), - IIC_iALUi, "sub", ".w\t$Rd, $sp, $imm", []> { +def t2SUBrSPi : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), + IIC_iALUi, "sub", ".w\t$Rd, $Rn, $imm", []> { let Inst{31-27} = 0b11110; let Inst{25} = 0; let Inst{24-21} = 0b1101; - let Inst{19-16} = 0b1101; // Rn = sp let Inst{15} = 0; } -def t2SUBrSPi12 : T2TwoRegImm<(outs GPR:$Rd), (ins GPR:$sp, imm0_4095:$imm), - IIC_iALUi, "subw", "\t$Rd, $sp, $imm", []> { - bits<4> Rd; - bits<12> imm; +def t2SUBrSPi12 : T2TwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm), + IIC_iALUi, "subw", "\t$Rd, $Rn, $imm", []> { let Inst{31-27} = 0b11110; - let Inst{26} = imm{11}; let Inst{25-20} = 0b101010; - let Inst{19-16} = 0b1101; // Rn = sp let Inst{15} = 0; - let Inst{14-12} = imm{10-8}; - let Inst{11-8} = Rd; - let Inst{7-0} = imm{7-0}; } // SUB r, sp, so_reg -def t2SUBrSPs : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$sp, t2_so_reg:$imm), +def t2SUBrSPs : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$Rn, t2_so_reg:$imm), IIC_iALUsi, - "sub", "\t$Rd, $sp, $imm", []> { + "sub", "\t$Rd, $Rn, $imm", []> { let Inst{31-27} = 0b11101; let Inst{26-25} = 0b01; let Inst{24-21} = 0b1101; let Inst{19-16} = 0b1101; // Rn = sp let Inst{15} = 0; } +} // end isCodeGenOnly = 1 // Signed and unsigned division on v7-M def t2SDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUi, @@ -1316,74 +1311,61 @@ def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)), // Indexed loads -class T2Iidxld opcod, bit pre, - dag oops, dag iops, - AddrMode am, IndexMode im, InstrItinClass itin, - string opc, string asm, string cstr, list pattern> - : T2Iidxldst; -class T2Iidxst opcod, bit pre, - dag oops, dag iops, - AddrMode am, IndexMode im, InstrItinClass itin, - string opc, string asm, string cstr, list pattern> - : T2Iidxldst; - let mayLoad = 1, neverHasSideEffects = 1 in { -def t2LDR_PRE : T2Iidxld<0, 0b10, 1, (outs GPR:$Rt, GPR:$Rn), +def t2LDR_PRE : T2Iidxldst<0, 0b10, 1, 1, (outs GPR:$Rt, GPR:$Rn), (ins t2addrmode_imm8:$addr), AddrModeT2_i8, IndexModePre, IIC_iLoad_iu, "ldr", "\t$Rt, $addr!", "$addr.base = $Rn", []>; -def t2LDR_POST : T2Iidxld<0, 0b10, 0, (outs GPR:$Rt, GPR:$Rn), - (ins GPR:$base, t2am_imm8_offset:$offset), +def t2LDR_POST : T2Iidxldst<0, 0b10, 1, 0, (outs GPR:$Rt, GPR:$Rn), + (ins GPR:$base, t2am_imm8_offset:$addr), AddrModeT2_i8, IndexModePost, IIC_iLoad_iu, - "ldr", "\t$Rt, [$Rn], $offset", "$base = $Rn", + "ldr", "\t$Rt, [$Rn], $addr", "$base = $Rn", []>; -def t2LDRB_PRE : T2Iidxld<0, 0b00, 1, (outs GPR:$Rt, GPR:$Rn), +def t2LDRB_PRE : T2Iidxldst<0, 0b00, 1, 1, (outs GPR:$Rt, GPR:$Rn), (ins t2addrmode_imm8:$addr), AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, "ldrb", "\t$Rt, $addr!", "$addr.base = $Rn", []>; -def t2LDRB_POST : T2Iidxld<0, 0b00, 0, (outs GPR:$Rt, GPR:$Rn), - (ins GPR:$base, t2am_imm8_offset:$offset), +def t2LDRB_POST : T2Iidxldst<0, 0b00, 1, 0, (outs GPR:$Rt, GPR:$Rn), + (ins GPR:$base, t2am_imm8_offset:$addr), AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu, - "ldrb", "\t$Rt, [$Rn], $offset", "$base = $Rn", + "ldrb", "\t$Rt, [$Rn], $addr", "$base = $Rn", []>; -def t2LDRH_PRE : T2Iidxld<0, 0b01, 1, (outs GPR:$Rt, GPR:$Rn), +def t2LDRH_PRE : T2Iidxldst<0, 0b01, 1, 1, (outs GPR:$Rt, GPR:$Rn), (ins t2addrmode_imm8:$addr), AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, "ldrh", "\t$Rt, $addr!", "$addr.base = $Rn", []>; -def t2LDRH_POST : T2Iidxld<0, 0b01, 0, (outs GPR:$Rt, GPR:$Rn), - (ins GPR:$base, t2am_imm8_offset:$offset), +def t2LDRH_POST : T2Iidxldst<0, 0b01, 1, 0, (outs GPR:$Rt, GPR:$Rn), + (ins GPR:$base, t2am_imm8_offset:$addr), AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu, - "ldrh", "\t$Rt, [$Rn], $offset", "$base = $Rn", + "ldrh", "\t$Rt, [$Rn], $addr", "$base = $Rn", []>; -def t2LDRSB_PRE : T2Iidxld<1, 0b00, 1, (outs GPR:$Rt, GPR:$Rn), +def t2LDRSB_PRE : T2Iidxldst<1, 0b00, 1, 1, (outs GPR:$Rt, GPR:$Rn), (ins t2addrmode_imm8:$addr), AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, "ldrsb", "\t$Rt, $addr!", "$addr.base = $Rn", []>; -def t2LDRSB_POST : T2Iidxld<1, 0b00, 0, (outs GPR:$Rt, GPR:$Rn), - (ins GPR:$base, t2am_imm8_offset:$offset), +def t2LDRSB_POST : T2Iidxldst<1, 0b00, 1, 0, (outs GPR:$Rt, GPR:$Rn), + (ins GPR:$base, t2am_imm8_offset:$addr), AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu, - "ldrsb", "\t$Rt, [$Rn], $offset", "$base = $Rn", + "ldrsb", "\t$Rt, [$Rn], $addr", "$base = $Rn", []>; -def t2LDRSH_PRE : T2Iidxld<1, 0b01, 1, (outs GPR:$Rt, GPR:$Rn), +def t2LDRSH_PRE : T2Iidxldst<1, 0b01, 1, 1, (outs GPR:$Rt, GPR:$Rn), (ins t2addrmode_imm8:$addr), AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, "ldrsh", "\t$Rt, $addr!", "$addr.base = $Rn", []>; -def t2LDRSH_POST : T2Iidxld<1, 0b01, 0, (outs GPR:$dst, GPR:$Rn), - (ins GPR:$base, t2am_imm8_offset:$offset), +def t2LDRSH_POST : T2Iidxldst<1, 0b01, 1, 0, (outs GPR:$dst, GPR:$Rn), + (ins GPR:$base, t2am_imm8_offset:$addr), AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu, - "ldrsh", "\t$dst, [$Rn], $offset", "$base = $Rn", + "ldrsh", "\t$dst, [$Rn], $addr", "$base = $Rn", []>; } // mayLoad = 1, neverHasSideEffects = 1 @@ -1430,42 +1412,42 @@ def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs), IIC_iStore_d_r, "strd", "\t$Rt, $Rt2, $addr", []>; // Indexed stores -def t2STR_PRE : T2Iidxst<0, 0b10, 1, (outs GPR:$base_wb), +def t2STR_PRE : T2Iidxldst<0, 0b10, 0, 1, (outs GPR:$base_wb), (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr), AddrModeT2_i8, IndexModePre, IIC_iStore_iu, "str", "\t$Rt, [$Rn, $addr]!", "$Rn = $base_wb", [(set GPR:$base_wb, (pre_store GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>; -def t2STR_POST : T2Iidxst<0, 0b10, 0, (outs GPR:$base_wb), +def t2STR_POST : T2Iidxldst<0, 0b10, 0, 0, (outs GPR:$base_wb), (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr), AddrModeT2_i8, IndexModePost, IIC_iStore_iu, "str", "\t$Rt, [$Rn], $addr", "$Rn = $base_wb", [(set GPR:$base_wb, (post_store GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>; -def t2STRH_PRE : T2Iidxst<0, 0b01, 1, (outs GPR:$base_wb), +def t2STRH_PRE : T2Iidxldst<0, 0b01, 0, 1, (outs GPR:$base_wb), (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr), AddrModeT2_i8, IndexModePre, IIC_iStore_iu, "strh", "\t$Rt, [$Rn, $addr]!", "$Rn = $base_wb", [(set GPR:$base_wb, (pre_truncsti16 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>; -def t2STRH_POST : T2Iidxst<0, 0b01, 0, (outs GPR:$base_wb), +def t2STRH_POST : T2Iidxldst<0, 0b01, 0, 0, (outs GPR:$base_wb), (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr), AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu, "strh", "\t$Rt, [$Rn], $addr", "$Rn = $base_wb", [(set GPR:$base_wb, (post_truncsti16 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>; -def t2STRB_PRE : T2Iidxst<0, 0b00, 1, (outs GPR:$base_wb), +def t2STRB_PRE : T2Iidxldst<0, 0b00, 0, 1, (outs GPR:$base_wb), (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr), AddrModeT2_i8, IndexModePre, IIC_iStore_bh_iu, "strb", "\t$Rt, [$Rn, $addr]!", "$Rn = $base_wb", [(set GPR:$base_wb, (pre_truncsti8 GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr))]>; -def t2STRB_POST : T2Iidxst<0, 0b00, 0, (outs GPR:$base_wb), +def t2STRB_POST : T2Iidxldst<0, 0b00, 0, 0, (outs GPR:$base_wb), (ins GPR:$Rt, GPR:$Rn, t2am_imm8_offset:$addr), AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu, "strb", "\t$Rt, [$Rn], $addr", "$Rn = $base_wb", @@ -2842,6 +2824,11 @@ def t2LDREX : Thumb2I<(outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone, let Inst{26-20} = 0b0000101; let Inst{11-8} = 0b1111; let Inst{7-0} = 0b00000000; // imm8 = 0 + + bits<4> Rn; + bits<4> Rt; + let Inst{19-16} = Rn; + let Inst{15-12} = Rt; } def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$Rt, rGPR:$Rt2), (ins rGPR:$Rn), AddrModeNone, Size4Bytes, NoItinerary, @@ -2866,6 +2853,13 @@ def t2STREX : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn), let Inst{31-27} = 0b11101; let Inst{26-20} = 0b0000100; let Inst{7-0} = 0b00000000; // imm8 = 0 + + bits<4> Rd; + bits<4> Rn; + bits<4> Rt; + let Inst{11-8} = Rd; + let Inst{19-16} = Rn; + let Inst{15-12} = Rt; } def t2STREXD : T2I_strex<0b11, (outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rt2, rGPR:$Rn), @@ -2967,7 +2961,7 @@ def t2LDMIA_RET: T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, let isBranch = 1, isTerminator = 1, isBarrier = 1 in { let isPredicable = 1 in -def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br, +def t2B : T2XI<(outs), (ins uncondbrtarget:$target), IIC_Br, "b.w\t$target", [(br bb:$target)]> { let Inst{31-27} = 0b11110; @@ -3031,13 +3025,16 @@ def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br, let Inst{31-27} = 0b11110; let Inst{15-14} = 0b10; let Inst{12} = 0; - - bits<20> target; - let Inst{26} = target{19}; - let Inst{11} = target{18}; - let Inst{13} = target{17}; - let Inst{21-16} = target{16-11}; - let Inst{10-0} = target{10-0}; + + bits<4> p; + let Inst{25-22} = p; + + bits<21> target; + let Inst{26} = target{20}; + let Inst{11} = target{19}; + let Inst{13} = target{18}; + let Inst{21-16} = target{17-12}; + let Inst{10-0} = target{11-1}; }