diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.td b/llvm/lib/Target/AVR/AVRInstrInfo.td --- a/llvm/lib/Target/AVR/AVRInstrInfo.td +++ b/llvm/lib/Target/AVR/AVRInstrInfo.td @@ -213,7 +213,7 @@ def imm16 : Operand { let EncoderMethod = "encodeImm"; } // A 7-bit address (which can lead to an R_AVR_LDS_STS_16 relocation). -def imm7tiny : Operand { +def imm7tiny : Operand { let EncoderMethod = "encodeImm"; } @@ -1295,7 +1295,8 @@ // Load from data space into register, which is only available on AVRTiny. def LDSRdKTiny : FLDSSTSTINY<0b0, (outs LD8:$rd), (ins imm7tiny:$k), - "lds\t$rd, $k", []>, + "lds\t$rd, $k", + [(set i8:$rd, (load imm:$k))]>, Requires<[HasSRAM, HasTinyEncoding]>; // LDSW Rd+1:Rd, K+1:K @@ -1518,7 +1519,7 @@ // Store from register to data space, which is only available on AVRTiny. def STSKRrTiny : FLDSSTSTINY<0b1, (outs), (ins imm7tiny:$k, LD8:$rd), - "sts\t$k, $rd", []>, + "sts\t$k, $rd", [(store i8:$rd, imm:$k)]>, Requires<[HasSRAM, HasTinyEncoding]>; // STSW K+1:K, Rr+1:Rr @@ -2521,12 +2522,18 @@ def : Pat<(i8(load(AVRWrapper tglobaladdr:$dst))), (LDSRdK tglobaladdr:$dst)>, Requires<[HasSRAM, HasNonTinyEncoding]>; +def : Pat<(i8(load(AVRWrapper tglobaladdr:$dst))), + (LDSRdKTiny tglobaladdr:$dst)>, + Requires<[HasSRAM, HasTinyEncoding]>; def : Pat<(i16(load(AVRWrapper tglobaladdr:$dst))), (LDSWRdK tglobaladdr:$dst)>, Requires<[HasSRAM, HasNonTinyEncoding]>; def : Pat<(store i8:$src, (i16(AVRWrapper tglobaladdr:$dst))), (STSKRr tglobaladdr:$dst, i8:$src)>, Requires<[HasSRAM, HasNonTinyEncoding]>; +def : Pat<(store i8:$src, (i16(AVRWrapper tglobaladdr:$dst))), + (STSKRrTiny tglobaladdr:$dst, i8:$src)>, + Requires<[HasSRAM, HasTinyEncoding]>; def : Pat<(store i16:$src, (i16(AVRWrapper tglobaladdr:$dst))), (STSWKRr tglobaladdr:$dst, i16:$src)>, Requires<[HasSRAM, HasNonTinyEncoding]>; diff --git a/llvm/test/CodeGen/AVR/directmem.ll b/llvm/test/CodeGen/AVR/directmem.ll --- a/llvm/test/CodeGen/AVR/directmem.ll +++ b/llvm/test/CodeGen/AVR/directmem.ll @@ -21,11 +21,10 @@ ; CHECK-LABEL: global8_store: ; CHECK: ldi [[REG:r[0-9]+]], 6 ; CHECK: sts char, [[REG]] +; ; CHECK-TINY-LABEL: global8_store: -; CHECK-TINY: ldi [[REG1:r[0-9]+]], 6 -; CHECK-TINY: ldi [[REG2:r[0-9]+]], lo8(char) -; CHECK-TINY: ldi [[REG3:r[0-9]+]], hi8(char) -; CHECK-TINY: st [[REG4:[X-Z]]], [[REG1]] +; CHECK-TINY: ldi [[REG:r[0-9]+]], 6 +; CHECK-TINY: sts char, [[REG]] store i8 6, i8* @char ret void } @@ -33,10 +32,9 @@ define i8 @global8_load() { ; CHECK-LABEL: global8_load: ; CHECK: lds r24, char +; ; CHECK-TINY-LABEL: global8_load: -; CHECK-TINY: ldi [[REG1:r[0-9]+]], lo8(char) -; CHECK-TINY: ldi [[REG2:r[0-9]+]], hi8(char) -; CHECK-TINY: ld [[REG3:r[0-9]+]], [[REG4:[X-Z]]] +; CHECK-TINY: lds r24, char %result = load i8, i8* @char ret i8 %result } @@ -49,6 +47,10 @@ ; CHECK: ldi [[REG2:r[0-9]+]], 2 ; CHECK: sts char.array+1, [[REG2]] ; CHECK: sts char.array, [[REG3]] +; +; CHECK-TINY-LABEL: array8_store: +; CHECK-TINY: ldi [[REG1:r[0-9]+]], 3 +; CHECK-TINY: sts char.array+2, [[REG1]] store i8 1, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @char.array, i32 0, i64 0) store i8 2, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @char.array, i32 0, i64 1) store i8 3, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @char.array, i32 0, i64 2) @@ -58,6 +60,9 @@ define i8 @array8_load() { ; CHECK-LABEL: array8_load: ; CHECK: lds r24, char.array+2 +; +; CHECK-TINY-LABEL: array8_load: +; CHECK-TINY: lds r24, char.array+2 %result = load i8, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @char.array, i32 0, i64 2) ret i8 %result } @@ -67,6 +72,11 @@ ; CHECK: lds r24, char.static ; CHECK: inc r24 ; CHECK: sts char.static, r24 +; +; CHECK-TINY-LABEL: static8_inc: +; CHECK-TINY: lds r24, char.static +; CHECK-TINY: inc r24 +; CHECK-TINY: sts char.static, r24 %1 = load i8, i8* @char.static %inc = add nsw i8 %1, 1 store i8 %inc, i8* @char.static