mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-19 18:24:00 +00:00
Add 64-bit load and store instructions.
There is only a few new instructions, the rest is handled with patterns. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178528 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -171,3 +171,71 @@ def : Pat<(add i64:$a, (i64 simm13:$b)), (ADDri $a, (as_i32imm $b))>;
|
|||||||
def : Pat<(sub i64:$a, (i64 simm13:$b)), (SUBri $a, (as_i32imm $b))>;
|
def : Pat<(sub i64:$a, (i64 simm13:$b)), (SUBri $a, (as_i32imm $b))>;
|
||||||
|
|
||||||
} // Predicates = [Is64Bit]
|
} // Predicates = [Is64Bit]
|
||||||
|
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// 64-bit Loads and Stores.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// All the 32-bit loads and stores are available. The extending loads are sign
|
||||||
|
// or zero-extending to 64 bits. The LDrr and LDri instructions load 32 bits
|
||||||
|
// zero-extended to i64. Their mnemonic is lduw in SPARC v9 (Load Unsigned
|
||||||
|
// Word).
|
||||||
|
//
|
||||||
|
// SPARC v9 adds 64-bit loads as well as a sign-extending ldsw i32 loads.
|
||||||
|
|
||||||
|
let Predicates = [Is64Bit] in {
|
||||||
|
|
||||||
|
// 64-bit loads.
|
||||||
|
def LDXrr : F3_1<3, 0b001011,
|
||||||
|
(outs I64Regs:$dst), (ins MEMrr:$addr),
|
||||||
|
"ldx [$addr], $dst",
|
||||||
|
[(set i64:$dst, (load ADDRrr:$addr))]>;
|
||||||
|
def LDXri : F3_2<3, 0b001011,
|
||||||
|
(outs I64Regs:$dst), (ins MEMri:$addr),
|
||||||
|
"ldx [$addr], $dst",
|
||||||
|
[(set i64:$dst, (load ADDRri:$addr))]>;
|
||||||
|
|
||||||
|
// Extending loads to i64.
|
||||||
|
def : Pat<(i64 (zextloadi8 ADDRrr:$addr)), (LDUBrr ADDRrr:$addr)>;
|
||||||
|
def : Pat<(i64 (zextloadi8 ADDRri:$addr)), (LDUBri ADDRri:$addr)>;
|
||||||
|
def : Pat<(i64 (sextloadi8 ADDRrr:$addr)), (LDSBrr ADDRrr:$addr)>;
|
||||||
|
def : Pat<(i64 (sextloadi8 ADDRri:$addr)), (LDSBri ADDRri:$addr)>;
|
||||||
|
|
||||||
|
def : Pat<(i64 (zextloadi16 ADDRrr:$addr)), (LDUHrr ADDRrr:$addr)>;
|
||||||
|
def : Pat<(i64 (zextloadi16 ADDRri:$addr)), (LDUHri ADDRri:$addr)>;
|
||||||
|
def : Pat<(i64 (sextloadi16 ADDRrr:$addr)), (LDSHrr ADDRrr:$addr)>;
|
||||||
|
def : Pat<(i64 (sextloadi16 ADDRri:$addr)), (LDSHri ADDRri:$addr)>;
|
||||||
|
|
||||||
|
def : Pat<(i64 (zextloadi32 ADDRrr:$addr)), (LDrr ADDRrr:$addr)>;
|
||||||
|
def : Pat<(i64 (zextloadi32 ADDRri:$addr)), (LDri ADDRri:$addr)>;
|
||||||
|
|
||||||
|
// Sign-extending load of i32 into i64 is a new SPARC v9 instruction.
|
||||||
|
def LDSWrr : F3_1<3, 0b001011,
|
||||||
|
(outs I64Regs:$dst), (ins MEMrr:$addr),
|
||||||
|
"ldsw [$addr], $dst",
|
||||||
|
[(set i64:$dst, (sextloadi32 ADDRrr:$addr))]>;
|
||||||
|
def LDSWri : F3_2<3, 0b001011,
|
||||||
|
(outs I64Regs:$dst), (ins MEMri:$addr),
|
||||||
|
"ldsw [$addr], $dst",
|
||||||
|
[(set i64:$dst, (sextloadi32 ADDRri:$addr))]>;
|
||||||
|
|
||||||
|
// 64-bit stores.
|
||||||
|
def STXrr : F3_1<3, 0b001110,
|
||||||
|
(outs), (ins MEMrr:$addr, I64Regs:$src),
|
||||||
|
"stx $src, [$addr]",
|
||||||
|
[(store i64:$src, ADDRrr:$addr)]>;
|
||||||
|
def STXri : F3_2<3, 0b001110,
|
||||||
|
(outs), (ins MEMri:$addr, I64Regs:$src),
|
||||||
|
"stx $src, [$addr]",
|
||||||
|
[(store i64:$src, ADDRri:$addr)]>;
|
||||||
|
|
||||||
|
// Truncating stores from i64 are identical to the i32 stores.
|
||||||
|
def : Pat<(truncstorei8 i64:$src, ADDRrr:$addr), (STBrr ADDRrr:$addr, $src)>;
|
||||||
|
def : Pat<(truncstorei8 i64:$src, ADDRri:$addr), (STBri ADDRri:$addr, $src)>;
|
||||||
|
def : Pat<(truncstorei16 i64:$src, ADDRrr:$addr), (STHrr ADDRrr:$addr, $src)>;
|
||||||
|
def : Pat<(truncstorei16 i64:$src, ADDRri:$addr), (STHri ADDRri:$addr, $src)>;
|
||||||
|
def : Pat<(truncstorei32 i64:$src, ADDRrr:$addr), (STrr ADDRrr:$addr, $src)>;
|
||||||
|
def : Pat<(truncstorei32 i64:$src, ADDRri:$addr), (STri ADDRri:$addr, $src)>;
|
||||||
|
|
||||||
|
} // Predicates = [Is64Bit]
|
||||||
|
@ -86,3 +86,61 @@ define i64 @reg_imm_alu(i64 %x, i64 %y, i64 %z) {
|
|||||||
%b = xor i64 %a, 2
|
%b = xor i64 %a, 2
|
||||||
ret i64 %b
|
ret i64 %b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; CHECK: loads
|
||||||
|
; CHECK: ldx [%i0]
|
||||||
|
; CHECK: stx %
|
||||||
|
; CHECK: ld [%i1]
|
||||||
|
; CHECK: st %
|
||||||
|
; CHECK: ldsw [%i2]
|
||||||
|
; CHECK: stx %
|
||||||
|
; CHECK: ldsh [%i3]
|
||||||
|
; CHECK: sth %
|
||||||
|
define i64 @loads(i64* %p, i32* %q, i32* %r, i16* %s) {
|
||||||
|
%a = load i64* %p
|
||||||
|
%ai = add i64 1, %a
|
||||||
|
store i64 %ai, i64* %p
|
||||||
|
%b = load i32* %q
|
||||||
|
%b2 = zext i32 %b to i64
|
||||||
|
%bi = trunc i64 %ai to i32
|
||||||
|
store i32 %bi, i32* %q
|
||||||
|
%c = load i32* %r
|
||||||
|
%c2 = sext i32 %c to i64
|
||||||
|
store i64 %ai, i64* %p
|
||||||
|
%d = load i16* %s
|
||||||
|
%d2 = sext i16 %d to i64
|
||||||
|
%di = trunc i64 %ai to i16
|
||||||
|
store i16 %di, i16* %s
|
||||||
|
|
||||||
|
%x1 = add i64 %a, %b2
|
||||||
|
%x2 = add i64 %c2, %d2
|
||||||
|
%x3 = add i64 %x1, %x2
|
||||||
|
ret i64 %x3
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK: stores
|
||||||
|
; CHECK: ldx [%i0+8], [[R:%[goli][0-7]]]
|
||||||
|
; CHECK: stx [[R]], [%i0+16]
|
||||||
|
; CHECK: st [[R]], [%i1+-8]
|
||||||
|
; CHECK: sth [[R]], [%i2+40]
|
||||||
|
; CHECK: stb [[R]], [%i3+-20]
|
||||||
|
define void @stores(i64* %p, i32* %q, i16* %r, i8* %s) {
|
||||||
|
%p1 = getelementptr i64* %p, i64 1
|
||||||
|
%p2 = getelementptr i64* %p, i64 2
|
||||||
|
%pv = load i64* %p1
|
||||||
|
store i64 %pv, i64* %p2
|
||||||
|
|
||||||
|
%q2 = getelementptr i32* %q, i32 -2
|
||||||
|
%qv = trunc i64 %pv to i32
|
||||||
|
store i32 %qv, i32* %q2
|
||||||
|
|
||||||
|
%r2 = getelementptr i16* %r, i16 20
|
||||||
|
%rv = trunc i64 %pv to i16
|
||||||
|
store i16 %rv, i16* %r2
|
||||||
|
|
||||||
|
%s2 = getelementptr i8* %s, i8 -20
|
||||||
|
%sv = trunc i64 %pv to i8
|
||||||
|
store i8 %sv, i8* %s2
|
||||||
|
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user