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,
ASSERT(regs != 0);
EmitMultiMemOp(cond, am, false, base, regs);
}
#endif
// Moved to ARM::AssemblerARM32::ldrex();
void Assembler::ldrex(Register rt, Register rn, Condition cond) {
ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE);
ASSERT(rn != kNoRegister);
......@@ -573,7 +572,7 @@ void Assembler::ldrex(Register rt, Register rn, Condition cond) {
Emit(encoding);
}
// Moved to ARM::AssemblerARM32::strex();
void Assembler::strex(Register rd, Register rt, Register rn, Condition cond) {
ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE);
ASSERT(rn != kNoRegister);
......@@ -589,7 +588,7 @@ void Assembler::strex(Register rd, Register rt, Register rn, Condition cond) {
(static_cast<int32_t>(rt) << kStrExRtShift);
Emit(encoding);
}
#endif
void Assembler::clrex() {
ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE);
......
......@@ -588,10 +588,12 @@ class Assembler : public ValueObject {
// (and doesn't implement ARM STM instruction).
void stm(BlockAddressMode am, Register base,
RegList regs, Condition cond = AL);
#endif
// Moved to ARM::AssemblerARM32::ldrex();
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);
#endif
// Miscellaneous instructions.
void clrex();
......
......@@ -225,6 +225,15 @@ public:
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,
bool SetFlags, CondARM32::Cond Cond);
......@@ -283,6 +292,15 @@ public:
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,
bool SetFlags, CondARM32::Cond Cond);
......@@ -378,6 +396,12 @@ private:
const Operand *OpAddress, const TargetInfo &TInfo,
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,
// aaaa<<21=AddressMode, l=IsLoad, nnnn=BaseReg, and
// rrrrrrrrrrrrrrrr is bitset of Registers.
......
......@@ -1181,6 +1181,17 @@ template <> void InstARM32Ldrex::emit(const Cfg *Func) const {
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>
void InstARM32TwoAddrGPR<K>::emitIAS(const Cfg *Func) const {
emitUsingTextFixup(Func);
......@@ -1590,6 +1601,16 @@ void InstARM32Strex::emit(const Cfg *Func) const {
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 {
if (!BuildDefs::dump())
return;
......
......@@ -1166,6 +1166,7 @@ public:
InstARM32Strex(Func, Dest, 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, 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