Commit e3455053 by Karl Schimpf

Add "sub immediate" instruction to the ARM integrated assembler.

parent 372bdd6e
...@@ -28,6 +28,7 @@ using namespace Ice; ...@@ -28,6 +28,7 @@ using namespace Ice;
// The following define individual bits. // The following define individual bits.
static constexpr uint32_t B0 = 1; static constexpr uint32_t B0 = 1;
static constexpr uint32_t B1 = 1 << 1;
static constexpr uint32_t B2 = 1 << 2; static constexpr uint32_t B2 = 1 << 2;
static constexpr uint32_t B3 = 1 << 3; static constexpr uint32_t B3 = 1 << 3;
static constexpr uint32_t B4 = 1 << 4; static constexpr uint32_t B4 = 1 << 4;
...@@ -220,4 +221,34 @@ void ARM32::AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc, ...@@ -220,4 +221,34 @@ void ARM32::AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc,
UnimplementedError(Ctx->getFlags()); UnimplementedError(Ctx->getFlags());
} }
void ARM32::AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn,
const Operand *OpSrc1, bool SetFlags,
CondARM32::Cond Cond) {
// Note: Loop is used so that we can short circuit using break;
do {
uint32_t Rd;
if (decode(OpRd, Rd) != DecodedAsRegister)
break;
uint32_t Rn;
if (decode(OpRn, Rn) != DecodedAsRegister)
break;
uint32_t Src1Value;
// TODO(kschimpf) Other possible decodings of add.
if (decode(OpSrc1, Src1Value) == DecodedAsRotatedImm8) {
// Sub (Immediate): See ARM section A8.8.222, rule A1.
// cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
// s=SetFlags and iiiiiiiiiiii=Src1Value
if (!isConditionDefined(Cond) || (Rd == RegARM32::Reg_pc && SetFlags) ||
(Rn == RegARM32::Reg_lr) || (Rn == RegARM32::Reg_pc && SetFlags))
// Conditions of rule violated.
break;
uint32_t Add = B1; // 0010
uint32_t InstType = 1;
emitType01(Cond, InstType, Add, SetFlags, Rn, Rd, Src1Value);
return;
}
} while (0);
UnimplementedError(Ctx->getFlags());
}
} // end of namespace Ice } // end of namespace Ice
...@@ -107,6 +107,9 @@ public: ...@@ -107,6 +107,9 @@ public:
void bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond = CondARM32::AL); void bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond = CondARM32::AL);
void sub(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
bool SetFlags, CondARM32::Cond Cond);
static bool classof(const Assembler *Asm) { static bool classof(const Assembler *Asm) {
return Asm->getKind() == Asm_ARM32; return Asm->getKind() == Asm_ARM32;
} }
......
...@@ -330,6 +330,12 @@ void InstARM32ThreeAddrGPR<InstARM32::Add>::emitIAS(const Cfg *Func) const { ...@@ -330,6 +330,12 @@ void InstARM32ThreeAddrGPR<InstARM32::Add>::emitIAS(const Cfg *Func) const {
Asm->add(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); Asm->add(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
} }
template <>
void InstARM32ThreeAddrGPR<InstARM32::Sub>::emitIAS(const Cfg *Func) const {
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->sub(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
}
InstARM32Call::InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget) InstARM32Call::InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget)
: InstARM32(Func, InstARM32::Call, 1, Dest) { : InstARM32(Func, InstARM32::Call, 1, Dest) {
HasSideEffects = true; HasSideEffects = true;
......
...@@ -14,11 +14,11 @@ define internal i32 @add1ToR0(i32 %p) { ...@@ -14,11 +14,11 @@ define internal i32 @add1ToR0(i32 %p) {
} }
; ASM-LABEL: add1ToR0: ; ASM-LABEL: add1ToR0:
; ASM: add r0, r0, #1 ; ASM: add r0, r0, #1
; ASM: bx lr ; ASM: bx lr
; IASM-LABEL: add1ToR0: ; IASM-LABEL: add1ToR0:
; IASM: .byte 0x1 ; IASM: .byte 0x1
; IASM-NEXT: .byte 0x0 ; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x80 ; IASM-NEXT: .byte 0x80
; IASM-NEXT: .byte 0xe2 ; IASM-NEXT: .byte 0xe2
......
; Show that we know how to translate instruction sub.
; TODO(kschimpf) Currently only know how to test subtract 1 from R0.
; NOTE: We use -O2 to get rid of memory stores.
; RUN: %p2i --filetype=asm -i %s --target=arm32 --args -O2 \
; RUN: | FileCheck %s --check-prefix=ASM
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -O2 \
; RUN: | FileCheck %s --check-prefix=IASM
define internal i32 @sub1FromR0(i32 %p) {
%v = sub i32 %p, 1
ret i32 %v
}
; ASM-LABEL: sub1FromR0:
; ASM: sub r0, r0, #1
; ASM: bx lr
; IASM-LABEL: sub1FromR0:
; IASM: .byte 0x1
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x40
; IASM-NEXT: .byte 0xe2
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment