mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-27 13:30:05 +00:00
A few more load instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74500 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e9722fc850
commit
f3c21b857b
@ -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>;
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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))]>;
|
||||
let canFoldAsLoad = 1 in
|
||||
defm t2LDR : T2I_ld<"ldr", UnOpFrag<(load node:$Src)>>;
|
||||
|
||||
def t2LDRi8 : T2Ii8<(outs GPR:$dst), (ins t2addrmode_imm8:$addr),
|
||||
"ldr", " $dst, $addr",
|
||||
[(set GPR:$dst, (load t2addrmode_imm8:$addr))]>;
|
||||
// Loads with zero extension
|
||||
defm t2LDRH : T2I_ld<"ldrh", UnOpFrag<(zextloadi16 node:$Src)>>;
|
||||
defm t2LDRB : T2I_ld<"ldrb", UnOpFrag<(zextloadi8 node:$Src)>>;
|
||||
|
||||
def t2LDRs : T2Iso<(outs GPR:$dst), (ins t2addrmode_so_reg:$addr),
|
||||
"ldr", " $dst, $addr",
|
||||
[(set GPR:$dst, (load t2addrmode_so_reg:$addr))]>;
|
||||
// Loads with sign extension
|
||||
defm t2LDRSH : T2I_ld<"ldrsh", UnOpFrag<(sextloadi16 node:$Src)>>;
|
||||
defm t2LDRSB : T2I_ld<"ldrsb", UnOpFrag<(sextloadi8 node:$Src)>>;
|
||||
|
||||
// Load tconstpool
|
||||
def t2LDRpci : T2Ipc<(outs GPR:$dst), (ins i32imm:$addr),
|
||||
"ldr", " $dst, $addr",
|
||||
[(set GPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>;
|
||||
} // canFoldAsLoad
|
||||
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.
|
||||
|
28
test/CodeGen/Thumb2/thumb2-ldr_ext.ll
Normal file
28
test/CodeGen/Thumb2/thumb2-ldr_ext.ll
Normal file
@ -0,0 +1,28 @@
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep ldrb | count 1
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep ldrh | count 1
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep ldrsb | count 1
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep ldrsh | count 1
|
||||
|
||||
define i32 @test1(i8* %v.pntr.s0.u1) {
|
||||
%tmp.u = load i8* %v.pntr.s0.u1
|
||||
%tmp1.s = zext i8 %tmp.u to i32
|
||||
ret i32 %tmp1.s
|
||||
}
|
||||
|
||||
define i32 @test2(i16* %v.pntr.s0.u1) {
|
||||
%tmp.u = load i16* %v.pntr.s0.u1
|
||||
%tmp1.s = zext i16 %tmp.u to i32
|
||||
ret i32 %tmp1.s
|
||||
}
|
||||
|
||||
define i32 @test3(i8* %v.pntr.s1.u0) {
|
||||
%tmp.s = load i8* %v.pntr.s1.u0
|
||||
%tmp1.s = sext i8 %tmp.s to i32
|
||||
ret i32 %tmp1.s
|
||||
}
|
||||
|
||||
define i32 @test4() {
|
||||
%tmp.s = load i16* null
|
||||
%tmp1.s = sext i16 %tmp.s to i32
|
||||
ret i32 %tmp1.s
|
||||
}
|
60
test/CodeGen/Thumb2/thumb2-ldrb.ll
Normal file
60
test/CodeGen/Thumb2/thumb2-ldrb.ll
Normal file
@ -0,0 +1,60 @@
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep {ldrb r0} | count 7
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov | grep 1
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | not grep mvn
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep ldrb | grep lsl
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep lsr | not grep ldrb
|
||||
|
||||
define i8 @f1(i8* %v) {
|
||||
entry:
|
||||
%tmp = load i8* %v
|
||||
ret i8 %tmp
|
||||
}
|
||||
|
||||
define i8 @f2(i8* %v) {
|
||||
entry:
|
||||
%tmp2 = getelementptr i8* %v, i8 1023
|
||||
%tmp = load i8* %tmp2
|
||||
ret i8 %tmp
|
||||
}
|
||||
|
||||
define i8 @f3(i32 %base) {
|
||||
entry:
|
||||
%tmp1 = add i32 %base, 4096
|
||||
%tmp2 = inttoptr i32 %tmp1 to i8*
|
||||
%tmp3 = load i8* %tmp2
|
||||
ret i8 %tmp3
|
||||
}
|
||||
|
||||
define i8 @f4(i32 %base) {
|
||||
entry:
|
||||
%tmp1 = sub i32 %base, 128
|
||||
%tmp2 = inttoptr i32 %tmp1 to i8*
|
||||
%tmp3 = load i8* %tmp2
|
||||
ret i8 %tmp3
|
||||
}
|
||||
|
||||
define i8 @f5(i32 %base, i32 %offset) {
|
||||
entry:
|
||||
%tmp1 = add i32 %base, %offset
|
||||
%tmp2 = inttoptr i32 %tmp1 to i8*
|
||||
%tmp3 = load i8* %tmp2
|
||||
ret i8 %tmp3
|
||||
}
|
||||
|
||||
define i8 @f6(i32 %base, i32 %offset) {
|
||||
entry:
|
||||
%tmp1 = shl i32 %offset, 2
|
||||
%tmp2 = add i32 %base, %tmp1
|
||||
%tmp3 = inttoptr i32 %tmp2 to i8*
|
||||
%tmp4 = load i8* %tmp3
|
||||
ret i8 %tmp4
|
||||
}
|
||||
|
||||
define i8 @f7(i32 %base, i32 %offset) {
|
||||
entry:
|
||||
%tmp1 = lshr i32 %offset, 2
|
||||
%tmp2 = add i32 %base, %tmp1
|
||||
%tmp3 = inttoptr i32 %tmp2 to i8*
|
||||
%tmp4 = load i8* %tmp3
|
||||
ret i8 %tmp4
|
||||
}
|
59
test/CodeGen/Thumb2/thumb2-ldrh.ll
Normal file
59
test/CodeGen/Thumb2/thumb2-ldrh.ll
Normal file
@ -0,0 +1,59 @@
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep {ldrh r0} | count 7
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov | grep 1
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | not grep mvn
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep ldrh | grep lsl
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep lsr | not grep ldrh
|
||||
|
||||
define i16 @f1(i16* %v) {
|
||||
entry:
|
||||
%tmp = load i16* %v
|
||||
ret i16 %tmp
|
||||
}
|
||||
|
||||
define i16 @f2(i16* %v) {
|
||||
entry:
|
||||
%tmp2 = getelementptr i16* %v, i16 1023
|
||||
%tmp = load i16* %tmp2
|
||||
ret i16 %tmp
|
||||
}
|
||||
|
||||
define i16 @f3(i16* %v) {
|
||||
entry:
|
||||
%tmp2 = getelementptr i16* %v, i16 2048
|
||||
%tmp = load i16* %tmp2
|
||||
ret i16 %tmp
|
||||
}
|
||||
|
||||
define i16 @f4(i32 %base) {
|
||||
entry:
|
||||
%tmp1 = sub i32 %base, 128
|
||||
%tmp2 = inttoptr i32 %tmp1 to i16*
|
||||
%tmp3 = load i16* %tmp2
|
||||
ret i16 %tmp3
|
||||
}
|
||||
|
||||
define i16 @f5(i32 %base, i32 %offset) {
|
||||
entry:
|
||||
%tmp1 = add i32 %base, %offset
|
||||
%tmp2 = inttoptr i32 %tmp1 to i16*
|
||||
%tmp3 = load i16* %tmp2
|
||||
ret i16 %tmp3
|
||||
}
|
||||
|
||||
define i16 @f6(i32 %base, i32 %offset) {
|
||||
entry:
|
||||
%tmp1 = shl i32 %offset, 2
|
||||
%tmp2 = add i32 %base, %tmp1
|
||||
%tmp3 = inttoptr i32 %tmp2 to i16*
|
||||
%tmp4 = load i16* %tmp3
|
||||
ret i16 %tmp4
|
||||
}
|
||||
|
||||
define i16 @f7(i32 %base, i32 %offset) {
|
||||
entry:
|
||||
%tmp1 = lshr i32 %offset, 2
|
||||
%tmp2 = add i32 %base, %tmp1
|
||||
%tmp3 = inttoptr i32 %tmp2 to i16*
|
||||
%tmp4 = load i16* %tmp3
|
||||
ret i16 %tmp4
|
||||
}
|
Loading…
Reference in New Issue
Block a user