Commit 4175d45e by Karl Schimpf

Add various forms of LDREX/STREX to ARM integrated assembler.

parent 65f80d72
...@@ -555,9 +555,8 @@ void Assembler::stm(BlockAddressMode am, Register base, RegList regs, ...@@ -555,9 +555,8 @@ void Assembler::stm(BlockAddressMode am, Register base, RegList regs,
ASSERT(regs != 0); ASSERT(regs != 0);
EmitMultiMemOp(cond, am, false, base, regs); EmitMultiMemOp(cond, am, false, base, regs);
} }
#endif
// Moved to ARM::AssemblerARM32::ldrex();
void Assembler::ldrex(Register rt, Register rn, Condition cond) { void Assembler::ldrex(Register rt, Register rn, Condition cond) {
ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE); ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE);
ASSERT(rn != kNoRegister); ASSERT(rn != kNoRegister);
...@@ -573,7 +572,7 @@ void Assembler::ldrex(Register rt, Register rn, Condition cond) { ...@@ -573,7 +572,7 @@ void Assembler::ldrex(Register rt, Register rn, Condition cond) {
Emit(encoding); Emit(encoding);
} }
// Moved to ARM::AssemblerARM32::strex();
void Assembler::strex(Register rd, Register rt, Register rn, Condition cond) { void Assembler::strex(Register rd, Register rt, Register rn, Condition cond) {
ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE); ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE);
ASSERT(rn != kNoRegister); ASSERT(rn != kNoRegister);
...@@ -589,7 +588,7 @@ void Assembler::strex(Register rd, Register rt, Register rn, Condition cond) { ...@@ -589,7 +588,7 @@ void Assembler::strex(Register rd, Register rt, Register rn, Condition cond) {
(static_cast<int32_t>(rt) << kStrExRtShift); (static_cast<int32_t>(rt) << kStrExRtShift);
Emit(encoding); Emit(encoding);
} }
#endif
void Assembler::clrex() { void Assembler::clrex() {
ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE); ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE);
......
...@@ -588,10 +588,12 @@ class Assembler : public ValueObject { ...@@ -588,10 +588,12 @@ class Assembler : public ValueObject {
// (and doesn't implement ARM STM instruction). // (and doesn't implement ARM STM instruction).
void stm(BlockAddressMode am, Register base, void stm(BlockAddressMode am, Register base,
RegList regs, Condition cond = AL); RegList regs, Condition cond = AL);
#endif
// Moved to ARM::AssemblerARM32::ldrex();
void ldrex(Register rd, Register rn, Condition cond = AL); void ldrex(Register rd, Register rn, Condition cond = AL);
// Moved to ARM::AssemblerARM32::strex();
void strex(Register rd, Register rt, Register rn, Condition cond = AL); void strex(Register rd, Register rt, Register rn, Condition cond = AL);
#endif
// Miscellaneous instructions. // Miscellaneous instructions.
void clrex(); void clrex();
......
...@@ -225,6 +225,15 @@ public: ...@@ -225,6 +225,15 @@ public:
ldr(OpRt, OpAddress, Cond, TInfo); ldr(OpRt, OpAddress, Cond, TInfo);
} }
void ldrex(const Operand *OpRt, const Operand *OpAddress,
CondARM32::Cond Cond, const TargetInfo &TInfo);
void ldrex(const Operand *OpRt, const Operand *OpAddress,
CondARM32::Cond Cond, const TargetLowering *Lowering) {
const TargetInfo TInfo(Lowering);
ldrex(OpRt, OpAddress, Cond, TInfo);
}
void lsl(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1, void lsl(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
bool SetFlags, CondARM32::Cond Cond); bool SetFlags, CondARM32::Cond Cond);
...@@ -283,6 +292,15 @@ public: ...@@ -283,6 +292,15 @@ public:
str(OpRt, OpAddress, Cond, TInfo); str(OpRt, OpAddress, Cond, TInfo);
} }
void strex(const Operand *OpRd, const Operand *OpRt, const Operand *OpAddress,
CondARM32::Cond Cond, const TargetInfo &TInfo);
void strex(const Operand *OpRd, const Operand *OpRt, const Operand *OpAddress,
CondARM32::Cond Cond, const TargetLowering *Lowering) {
const TargetInfo TInfo(Lowering);
strex(OpRd, OpRt, OpAddress, Cond, TInfo);
}
void sub(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1, void sub(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
bool SetFlags, CondARM32::Cond Cond); bool SetFlags, CondARM32::Cond Cond);
...@@ -378,6 +396,12 @@ private: ...@@ -378,6 +396,12 @@ private:
const Operand *OpAddress, const TargetInfo &TInfo, const Operand *OpAddress, const TargetInfo &TInfo,
const char *InstName); const char *InstName);
// Emit cccc00011xxlnnnndddd11111001tttt where cccc=Cond, xx encodes type
// size, l=IsLoad, nnnn=Rn (as defined by OpAddress), and tttt=Rt.
void emitMemExOp(CondARM32::Cond, Type Ty, bool IsLoad, const Operand *OpRd,
IValueT Rt, const Operand *OpAddress,
const TargetInfo &TInfo, const char *InstName);
// Pattern cccc100aaaalnnnnrrrrrrrrrrrrrrrr where cccc=Cond, // Pattern cccc100aaaalnnnnrrrrrrrrrrrrrrrr where cccc=Cond,
// aaaa<<21=AddressMode, l=IsLoad, nnnn=BaseReg, and // aaaa<<21=AddressMode, l=IsLoad, nnnn=BaseReg, and
// rrrrrrrrrrrrrrrr is bitset of Registers. // rrrrrrrrrrrrrrrr is bitset of Registers.
......
...@@ -1181,6 +1181,17 @@ template <> void InstARM32Ldrex::emit(const Cfg *Func) const { ...@@ -1181,6 +1181,17 @@ template <> void InstARM32Ldrex::emit(const Cfg *Func) const {
getSrc(0)->emit(Func); getSrc(0)->emit(Func);
} }
template <> void InstARM32Ldrex::emitIAS(const Cfg *Func) const {
assert(getSrcSize() == 1);
assert(getDest()->hasReg());
Variable *Dest = getDest();
assert(isScalarIntegerType(Dest->getType()));
auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->ldrex(Dest, getSrc(0), getPredicate(), Func->getTarget());
if (Asm->needsTextFixup())
emitUsingTextFixup(Func);
}
template <InstARM32::InstKindARM32 K> template <InstARM32::InstKindARM32 K>
void InstARM32TwoAddrGPR<K>::emitIAS(const Cfg *Func) const { void InstARM32TwoAddrGPR<K>::emitIAS(const Cfg *Func) const {
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
...@@ -1590,6 +1601,16 @@ void InstARM32Strex::emit(const Cfg *Func) const { ...@@ -1590,6 +1601,16 @@ void InstARM32Strex::emit(const Cfg *Func) const {
emitSources(Func); emitSources(Func);
} }
void InstARM32Strex::emitIAS(const Cfg *Func) const {
assert(getSrcSize() == 2);
const Operand *Src0 = getSrc(0);
assert(isScalarIntegerType(Src0->getType()));
auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->strex(Dest, Src0, getSrc(1), getPredicate(), Func->getTarget());
if (Asm->needsTextFixup())
emitUsingTextFixup(Func);
}
void InstARM32Strex::dump(const Cfg *Func) const { void InstARM32Strex::dump(const Cfg *Func) const {
if (!BuildDefs::dump()) if (!BuildDefs::dump())
return; return;
......
...@@ -1166,6 +1166,7 @@ public: ...@@ -1166,6 +1166,7 @@ public:
InstARM32Strex(Func, Dest, Value, Mem, Predicate); InstARM32Strex(Func, Dest, 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, Strex); } static bool classof(const Inst *Inst) { return isClassof(Inst, Strex); }
......
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