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