Commit f0655b6c by Karl Schimpf

Add new form of ldr/str (immediate) to ARM integrated assembler.

parent 396de532
......@@ -98,6 +98,10 @@ inline IValueT encodeGPRRegister(RegARM32::GPRRegister Rn) {
return static_cast<IValueT>(Rn);
}
inline RegARM32::GPRRegister decodeGPRRegister(IValueT R) {
return static_cast<RegARM32::GPRRegister>(R);
}
inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) {
return R != RegARM32::Encoded_Not_GPR;
}
......@@ -142,7 +146,7 @@ inline bool isBitSet(IValueT Bit, IValueT Value) {
// Returns the GPR register at given Shift in Value.
inline RegARM32::GPRRegister getGPRReg(IValueT Shift, IValueT Value) {
return static_cast<RegARM32::GPRRegister>((Value >> Shift) & 0xF);
return decodeGPRRegister((Value >> Shift) & 0xF);
}
// The way an operand was decoded in functions decodeOperand and decodeAddress
......@@ -164,7 +168,7 @@ enum DecodedResult {
// Encodes iiiiitt0mmmm for data-processing (2nd) operands where iiiii=Imm5,
// tt=Shift, and mmmm=Rm.
IValueT encodeShiftRotateImm5(IValueT Rm, OperandARM32::ShiftKind Shift,
IValueT imm5) {
IOffsetT imm5) {
(void)kShiftImmBits;
assert(imm5 < (1 << kShiftImmBits));
return (imm5 << kShiftImmShift) | (encodeShift(Shift) << kShiftShift) | Rm;
......@@ -212,6 +216,18 @@ DecodedResult decodeAddress(const Operand *Opnd, IValueT &Value) {
OperandARM32Mem::Offset);
return DecodedAsImmRegOffset;
}
if (const auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Opnd)) {
if (Mem->isRegReg())
// TODO(kschimpf) Add this case.
return CantDecode;
Variable *Var = Mem->getBase();
if (!Var->hasReg())
return CantDecode;
ConstantInteger32 *Offset = Mem->getOffset();
Value = decodeImmRegOffset(decodeGPRRegister(Var->getRegNum()),
Offset->getValue(), Mem->getAddrMode());
return DecodedAsImmRegOffset;
}
return CantDecode;
}
......
......@@ -857,6 +857,11 @@ void InstARM32Label::dump(const Cfg *Func) const {
Str << getName(Func) << ":";
}
template <InstARM32::InstKindARM32 K>
void InstARM32LoadBase<K>::emitIAS(const Cfg *Func) const {
emitUsingTextFixup(Func);
}
template <> void InstARM32Ldr::emit(const Cfg *Func) const {
if (!BuildDefs::dump())
return;
......@@ -878,6 +883,20 @@ template <> void InstARM32Ldr::emit(const Cfg *Func) const {
getSrc(0)->emit(Func);
}
template <> void InstARM32Ldr::emitIAS(const Cfg *Func) const {
assert(getSrcSize() == 1);
Variable *Dest = getDest();
Type DestTy = Dest->getType();
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
if (isVectorType(DestTy) || isScalarFloatingType(DestTy))
// TODO(kschimpf) Handle case.
Asm->setNeedsTextFixup();
else
Asm->ldr(Dest, getSrc(0), getPredicate());
if (Asm->needsTextFixup())
emitUsingTextFixup(Func);
}
template <> void InstARM32Ldrex::emit(const Cfg *Func) const {
if (!BuildDefs::dump())
return;
......@@ -1128,6 +1147,19 @@ void InstARM32Str::emit(const Cfg *Func) const {
getSrc(1)->emit(Func);
}
void InstARM32Str::emitIAS(const Cfg *Func) const {
assert(getSrcSize() == 2);
Type Ty = getSrc(0)->getType();
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
if (isVectorType(Ty) || isScalarFloatingType(Ty))
// TODO(kschimpf) Handle case.
Asm->setNeedsTextFixup();
else
Asm->str(getSrc(0), getSrc(1), getPredicate());
if (Asm->needsTextFixup())
emitUsingTextFixup(Func);
}
void InstARM32Str::dump(const Cfg *Func) const {
if (!BuildDefs::dump())
return;
......@@ -1491,6 +1523,9 @@ template class InstARM32ThreeAddrFP<InstARM32::Vdiv>;
template class InstARM32ThreeAddrFP<InstARM32::Vmul>;
template class InstARM32ThreeAddrFP<InstARM32::Vsub>;
template class InstARM32LoadBase<InstARM32::Ldr>;
template class InstARM32LoadBase<InstARM32::Ldrex>;
template class InstARM32TwoAddrGPR<InstARM32::Movt>;
template class InstARM32UnaryopGPR<InstARM32::Movw, false>;
......
......@@ -538,6 +538,7 @@ public:
InstARM32LoadBase(Func, Dest, Source, Predicate);
}
void emit(const Cfg *Func) const override;
void emitIAS(const Cfg *Func) const override;
void dump(const Cfg *Func) const override {
if (!BuildDefs::dump())
return;
......@@ -1008,6 +1009,7 @@ public:
InstARM32Str(Func, Value, Mem, Predicate);
}
void emit(const Cfg *Func) const override;
void emitIAS(const Cfg *Func) const override;
void dump(const Cfg *Func) const override;
static bool classof(const Inst *Inst) { return isClassof(Inst, Str); }
......
......@@ -55,9 +55,12 @@ define internal i32 @load() {
; IASM-LABEL:load:
; IASM-NEXT: .Lload$__0:
; IASM-NEXT: movw r0, #:lower16:global1 @ .word e3000000
; IASM-NEXT: movt r0, #:upper16:global1 @ .word e3400000
; IASM-NEXT: ldr r0, [r0]
; IASM-NEXT: movw r0, #:lower16:global1
; IASM-NEXT: movt r0, #:upper16:global1
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x90
; IASM-NEXT: .byte 0xe5
; IASM-NEXT: .byte 0x1e
; IASM-NEXT: .byte 0xff
; IASM-NEXT: .byte 0x2f
......@@ -84,9 +87,12 @@ define internal void @store(i32 %v) {
; IASM-LABEL:store:
; IASM-NEXT: .Lstore$__0:
; IASM-NEXT: movw r1, #:lower16:global1 @ .word e3001000
; IASM-NEXT: movt r1, #:upper16:global1 @ .word e3401000
; IASM-NEXT: str r0, [r1]
; IASM-NEXT: movw r1, #:lower16:global1
; IASM-NEXT: movt r1, #:upper16:global1
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x81
; IASM-NEXT: .byte 0xe5
; IASM-NEXT: .byte 0x1e
; IASM-NEXT: .byte 0xff
; IASM-NEXT: .byte 0x2f
......
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