diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrFormats.td | 5 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrInfo.h | 29 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb.td | 10 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb2.td | 94 |
4 files changed, 99 insertions, 39 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrFormats.td b/llvm/lib/Target/ARM/ARMInstrFormats.td index a98bf1e8567..f49e38fb2ce 100644 --- a/llvm/lib/Target/ARM/ARMInstrFormats.td +++ b/llvm/lib/Target/ARM/ARMInstrFormats.td @@ -79,7 +79,8 @@ def AddrModeT1_s : AddrMode<9>; def AddrModeT2_i12: AddrMode<10>; def AddrModeT2_i8 : AddrMode<11>; def AddrModeT2_so : AddrMode<12>; -def AddrModeT2_pc : AddrMode<13>; +def AddrModeT2_pc : AddrMode<13>; +def AddrModeT2_i8s4 : AddrMode<14>; // Instruction size. class SizeFlagVal<bits<3> val> { @@ -856,6 +857,8 @@ class T2Iso<dag oops, dag iops, string opc, string asm, list<dag> pattern> : Thumb2I<oops, iops, AddrModeT2_so, Size4Bytes, opc, asm, "", pattern>; class T2Ipc<dag oops, dag iops, string opc, string asm, list<dag> pattern> : Thumb2I<oops, iops, AddrModeT2_pc, Size4Bytes, opc, asm, "", pattern>; +class T2Ii8s4<dag oops, dag iops, string opc, string asm, list<dag> pattern> + : Thumb2I<oops, iops, AddrModeT2_i8s4, Size4Bytes, opc, asm, "", pattern>; class T2sI<dag oops, dag iops, string opc, string asm, list<dag> pattern> : Thumb2sI<oops, iops, AddrModeNone, Size4Bytes, opc, asm, "", pattern>; diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.h b/llvm/lib/Target/ARM/ARMInstrInfo.h index ac1eec0921c..cdc420820d5 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.h +++ b/llvm/lib/Target/ARM/ARMInstrInfo.h @@ -33,20 +33,21 @@ namespace ARMII { // This four-bit field describes the addressing mode used. AddrModeMask = 0xf, - AddrModeNone = 0, - AddrMode1 = 1, - AddrMode2 = 2, - AddrMode3 = 3, - AddrMode4 = 4, - AddrMode5 = 5, - AddrModeT1_1 = 6, - AddrModeT1_2 = 7, - AddrModeT1_4 = 8, - AddrModeT1_s = 9, // i8 * 4 for pc and sp relative data - AddrModeT2_i12= 10, - AddrModeT2_i8 = 11, - AddrModeT2_so = 12, - AddrModeT2_pc = 13, // +/- i12 for pc relative data + AddrModeNone = 0, + AddrMode1 = 1, + AddrMode2 = 2, + AddrMode3 = 3, + AddrMode4 = 4, + AddrMode5 = 5, + AddrModeT1_1 = 6, + AddrModeT1_2 = 7, + AddrModeT1_4 = 8, + AddrModeT1_s = 9, // i8 * 4 for pc and sp relative data + AddrModeT2_i12 = 10, + AddrModeT2_i8 = 11, + AddrModeT2_so = 12, + AddrModeT2_pc = 13, // +/- i12 for pc relative data + AddrModeT2_i8s4 = 14, // i8 * 4 // Size* - Flags to keep track of the size of an instruction. SizeShift = 4, diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td index ae54a884ddd..c8e75384849 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb.td @@ -622,13 +622,13 @@ def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>; def : Tv5Pat<(ARMcall tGPR:$dst), (tBLXr tGPR:$dst)>; // zextload i1 -> zextload i8 -def : TPat<(zextloadi1 t_addrmode_s1:$addr), - (tLDRB t_addrmode_s1:$addr)>; +def : T1Pat<(zextloadi1 t_addrmode_s1:$addr), + (tLDRB t_addrmode_s1:$addr)>; // extload -> zextload -def : TPat<(extloadi1 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; -def : TPat<(extloadi8 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; -def : TPat<(extloadi16 t_addrmode_s2:$addr), (tLDRH t_addrmode_s2:$addr)>; +def : T1Pat<(extloadi1 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; +def : T1Pat<(extloadi8 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; +def : T1Pat<(extloadi16 t_addrmode_s2:$addr), (tLDRH t_addrmode_s2:$addr)>; // Large immediate handling. diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index 7a56fd75970..f848550a45b 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -136,7 +136,7 @@ def t2addrmode_imm12 : Operand<i32>, let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); } -// t2addrmode_imm8 := reg - imm8 +// t2addrmode_imm8 := reg - imm8 (also reg + imm8 for some instructions) def t2addrmode_imm8 : Operand<i32>, ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> { let PrintMethod = "printT2AddrModeImm8Operand"; @@ -383,6 +383,22 @@ multiclass T2I_cmp_is<string opc, PatFrag opnode> { } } +/// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns. +multiclass T2I_ld<string opc, PatFrag opnode> { + def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), + opc, " $dst, $addr", + [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]>; + def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), + opc, " $dst, $addr", + [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]>; + def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), + opc, " $dst, $addr", + [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]>; + def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), + opc, " $dst, $addr", + [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]>; +} + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -434,24 +450,64 @@ def t2ADDrSPs : T2XI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs), // // Load -let canFoldAsLoad = 1 in { -def t2LDRi12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), - "ldr", " $dst, $addr", - [(set GPR:$dst, (load t2addrmode_imm12:$addr))]>; - -def t2LDRi8 : T2Ii8<(outs GPR:$dst), (ins t2addrmode_imm8:$addr), - "ldr", " $dst, $addr", - [(set GPR:$dst, (load t2addrmode_imm8:$addr))]>; - -def t2LDRs : T2Iso<(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), - "ldr", " $dst, $addr", - [(set GPR:$dst, (load t2addrmode_so_reg:$addr))]>; - -// Load tconstpool -def t2LDRpci : T2Ipc<(outs GPR:$dst), (ins i32imm:$addr), - "ldr", " $dst, $addr", - [(set GPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>; -} // canFoldAsLoad +let canFoldAsLoad = 1 in +defm t2LDR : T2I_ld<"ldr", UnOpFrag<(load node:$Src)>>; + +// Loads with zero extension +defm t2LDRH : T2I_ld<"ldrh", UnOpFrag<(zextloadi16 node:$Src)>>; +defm t2LDRB : T2I_ld<"ldrb", UnOpFrag<(zextloadi8 node:$Src)>>; + +// Loads with sign extension +defm t2LDRSH : T2I_ld<"ldrsh", UnOpFrag<(sextloadi16 node:$Src)>>; +defm t2LDRSB : T2I_ld<"ldrsb", UnOpFrag<(sextloadi8 node:$Src)>>; + +let mayLoad = 1 in { +// Load doubleword +def t2LDRDi8 : T2Ii8s4<(outs GPR:$dst), (ins t2addrmode_imm8:$addr), + "ldrd", " $dst, $addr", []>; +def t2LDRDpci : T2Ii8s4<(outs GPR:$dst), (ins i32imm:$addr), + "ldrd", " $dst, $addr", []>; +} + +// zextload i1 -> zextload i8 +def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr), + (t2LDRBi12 t2addrmode_imm12:$addr)>; +def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr), + (t2LDRBi8 t2addrmode_imm8:$addr)>; +def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr), + (t2LDRBs t2addrmode_so_reg:$addr)>; +def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)), + (t2LDRBpci tconstpool:$addr)>; + +// extload -> zextload +// FIXME: Reduce the number of patterns by legalizing extload to zextload +// earlier? +def : T2Pat<(extloadi1 t2addrmode_imm12:$addr), + (t2LDRBi12 t2addrmode_imm12:$addr)>; +def : T2Pat<(extloadi1 t2addrmode_imm8:$addr), + (t2LDRBi8 t2addrmode_imm8:$addr)>; +def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr), + (t2LDRBs t2addrmode_so_reg:$addr)>; +def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)), + (t2LDRBpci tconstpool:$addr)>; + +def : T2Pat<(extloadi8 t2addrmode_imm12:$addr), + (t2LDRBi12 t2addrmode_imm12:$addr)>; +def : T2Pat<(extloadi8 t2addrmode_imm8:$addr), + (t2LDRBi8 t2addrmode_imm8:$addr)>; +def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr), + (t2LDRBs t2addrmode_so_reg:$addr)>; +def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)), + (t2LDRBpci tconstpool:$addr)>; + +def : T2Pat<(extloadi16 t2addrmode_imm12:$addr), + (t2LDRHi12 t2addrmode_imm12:$addr)>; +def : T2Pat<(extloadi16 t2addrmode_imm8:$addr), + (t2LDRHi8 t2addrmode_imm8:$addr)>; +def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr), + (t2LDRHs t2addrmode_so_reg:$addr)>; +def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)), + (t2LDRHpci tconstpool:$addr)>; //===----------------------------------------------------------------------===// // Move Instructions. |