| Index: src/IceAssemblerARM32.cpp
|
| diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp
|
| index 3470e918b9bb176a39ee005af7520c5aecfd8c37..46661299a1d3ca7df829e8b3ce43a6d88d192f67 100644
|
| --- a/src/IceAssemblerARM32.cpp
|
| +++ b/src/IceAssemblerARM32.cpp
|
| @@ -1688,13 +1688,50 @@ void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn,
|
| OrrName);
|
| }
|
|
|
| -void AssemblerARM32::pop(const Operand *OpRt, CondARM32::Cond Cond) {
|
| +void AssemblerARM32::emitStackTextOp(const Cfg *Func, const IValueT Registers,
|
| + CondARM32::Cond Cond,
|
| + const char *InstName) {
|
| + Ostream &Str = Func->getContext()->getStrEmit();
|
| + Str << "\t" << InstName << Cond << "\t{";
|
| + bool isFirst = true;
|
| + for (SizeT i = 0; i < RegARM32::getNumGPRegs(); ++i) {
|
| + if (mask(Registers, i, 1) == 0)
|
| + continue;
|
| + if (isFirst) {
|
| + isFirst = false;
|
| + } else {
|
| + Str << ", ";
|
| + }
|
| + Str << RegARM32::getGPRegName(i);
|
| + }
|
| + Str << "}";
|
| +}
|
| +
|
| +void AssemblerARM32::emitStackTextOp(const Cfg *Func, const Operand *OpRt,
|
| + CondARM32::Cond Cond,
|
| + const char *InstName) {
|
| + const IValueT Rt = encodeRegister(OpRt, "Rt", InstName);
|
| + const IValueT GPRegisters = 1 << Rt;
|
| + emitStackTextOp(Func, GPRegisters, Cond, InstName);
|
| +}
|
| +
|
| +template <>
|
| +void AssemblerARM32::pop<TextualAssembly>(const Cfg *Func, const Operand *OpRt,
|
| + CondARM32::Cond Cond) {
|
| + constexpr const char *Pop = "pop";
|
| + emitStackTextOp(Func, OpRt, Cond, Pop);
|
| +}
|
| +
|
| +template <>
|
| +void AssemblerARM32::pop<BinaryAssembly>(const Cfg *Func, const Operand *OpRt,
|
| + CondARM32::Cond Cond) {
|
| + (void)Func;
|
| // POP - ARM section A8.8.132, encoding A2:
|
| // pop<c> {Rt}
|
| //
|
| // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond.
|
| constexpr const char *Pop = "pop";
|
| - IValueT Rt = encodeRegister(OpRt, "Rt", Pop);
|
| + const IValueT Rt = encodeRegister(OpRt, "Rt", Pop);
|
| verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Pop);
|
| // Same as load instruction.
|
| constexpr bool IsLoad = true;
|
| @@ -1704,7 +1741,19 @@ void AssemblerARM32::pop(const Operand *OpRt, CondARM32::Cond Cond) {
|
| emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address, Pop);
|
| }
|
|
|
| -void AssemblerARM32::popList(const IValueT Registers, CondARM32::Cond Cond) {
|
| +template <>
|
| +void AssemblerARM32::popList<TextualAssembly>(const Cfg *Func,
|
| + const IValueT Registers,
|
| + CondARM32::Cond Cond) {
|
| + constexpr const char *PopList = "pop";
|
| + emitStackTextOp(Func, Registers, Cond, PopList);
|
| +}
|
| +
|
| +template <>
|
| +void AssemblerARM32::popList<BinaryAssembly>(const Cfg *Func,
|
| + const IValueT Registers,
|
| + CondARM32::Cond Cond) {
|
| + (void)Func;
|
| // POP - ARM section A8.*.131, encoding A1:
|
| // pop<c> <registers>
|
| //
|
| @@ -1716,7 +1765,17 @@ void AssemblerARM32::popList(const IValueT Registers, CondARM32::Cond Cond) {
|
| PopListName);
|
| }
|
|
|
| -void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) {
|
| +template <>
|
| +void AssemblerARM32::push<TextualAssembly>(const Cfg *Func, const Operand *OpRt,
|
| + CondARM32::Cond Cond) {
|
| + constexpr const char *Push = "push";
|
| + emitStackTextOp(Func, OpRt, Cond, Push);
|
| +}
|
| +
|
| +template <>
|
| +void AssemblerARM32::push<BinaryAssembly>(const Cfg *Func, const Operand *OpRt,
|
| + CondARM32::Cond Cond) {
|
| + (void)Func;
|
| // PUSH - ARM section A8.8.133, encoding A2:
|
| // push<c> {Rt}
|
| //
|
| @@ -1732,7 +1791,19 @@ void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) {
|
| emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address, Push);
|
| }
|
|
|
| -void AssemblerARM32::pushList(const IValueT Registers, CondARM32::Cond Cond) {
|
| +template <>
|
| +void AssemblerARM32::pushList<TextualAssembly>(const Cfg *Func,
|
| + const IValueT Registers,
|
| + CondARM32::Cond Cond) {
|
| + constexpr const char *PushList = "push";
|
| + emitStackTextOp(Func, Registers, Cond, PushList);
|
| +}
|
| +
|
| +template <>
|
| +void AssemblerARM32::pushList<BinaryAssembly>(const Cfg *Func,
|
| + const IValueT Registers,
|
| + CondARM32::Cond Cond) {
|
| + (void)Func;
|
| // PUSH - ARM section A8.8.133, encoding A1:
|
| // push<c> <Registers>
|
| //
|
| @@ -2006,10 +2077,37 @@ void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0,
|
| emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName);
|
| }
|
|
|
| -void AssemblerARM32::emitVStackOp(CondARM32::Cond Cond, IValueT Opcode,
|
| - const Variable *OpBaseReg,
|
| - SizeT NumConsecRegs, const char *InstName) {
|
| +template <>
|
| +void AssemblerARM32::emitVStackOp<TextualAssembly>(
|
| + const Cfg *Func, CondARM32::Cond Cond, IValueT Opcode,
|
| + const Variable *OpBaseReg, SizeT NumConsecRegs, const char *InstName) {
|
| + (void)Opcode;
|
| + if (!BuildDefs::dump())
|
| + return;
|
| +
|
| + Ostream &Str = Func->getContext()->getStrEmit();
|
| + Str << "\t" << InstName << Cond << "\t{";
|
| + IValueT BaseReg = getEncodedSRegNum(OpBaseReg);
|
| + assert(0 < NumConsecRegs);
|
| + assert(NumConsecRegs <= VpushVpopMaxConsecRegs);
|
| + assert((BaseReg + NumConsecRegs) <= RegARM32::getNumSRegs());
|
| + bool isFirst = true;
|
| + for (SizeT i = 0; i < NumConsecRegs; ++i) {
|
| + if (isFirst) {
|
| + isFirst = false;
|
| + } else {
|
| + Str << ", ";
|
| + }
|
| + Str << RegARM32::getSRegName(BaseReg + i);
|
| + }
|
| + Str << "}";
|
| +}
|
|
|
| +template <>
|
| +void AssemblerARM32::emitVStackOp<BinaryAssembly>(
|
| + const Cfg *Func, CondARM32::Cond Cond, IValueT Opcode,
|
| + const Variable *OpBaseReg, SizeT NumConsecRegs, const char *InstName) {
|
| + (void)Func;
|
| const IValueT BaseReg = getEncodedSRegNum(OpBaseReg);
|
| const IValueT DLastBit = mask(BaseReg, 0, 1); // Last bit of base register.
|
| const IValueT Rd = mask(BaseReg, 1, 4); // Top 4 bits of base register.
|
| @@ -2023,8 +2121,9 @@ void AssemblerARM32::emitVStackOp(CondARM32::Cond Cond, IValueT Opcode,
|
| emitInst(Encoding);
|
| }
|
|
|
| -void AssemblerARM32::vpop(const Variable *OpBaseReg, SizeT NumConsecRegs,
|
| - CondARM32::Cond Cond) {
|
| +template <AssemblyOutputForm Form>
|
| +void AssemblerARM32::vpop(const Cfg *Func, const Variable *OpBaseReg,
|
| + SizeT NumConsecRegs, CondARM32::Cond Cond) {
|
| // Note: Current implementation assumes that OpBaseReg is defined using S
|
| // registers. It doesn't implement the D register form.
|
| //
|
| @@ -2036,11 +2135,13 @@ void AssemblerARM32::vpop(const Variable *OpBaseReg, SizeT NumConsecRegs,
|
| constexpr const char *VpopName = "vpop";
|
| constexpr IValueT VpopOpcode =
|
| B27 | B26 | B23 | B21 | B20 | B19 | B18 | B16 | B11 | B9;
|
| - emitVStackOp(Cond, VpopOpcode, OpBaseReg, NumConsecRegs, VpopName);
|
| + emitVStackOp<Form>(Func, Cond, VpopOpcode, OpBaseReg, NumConsecRegs,
|
| + VpopName);
|
| }
|
|
|
| -void AssemblerARM32::vpush(const Variable *OpBaseReg, SizeT NumConsecRegs,
|
| - CondARM32::Cond Cond) {
|
| +template <AssemblyOutputForm Form>
|
| +void AssemblerARM32::vpush(const Cfg *Func, const Variable *OpBaseReg,
|
| + SizeT NumConsecRegs, CondARM32::Cond Cond) {
|
| // Note: Current implementation assumes that OpBaseReg is defined using S
|
| // registers. It doesn't implement the D register form.
|
| //
|
| @@ -2052,8 +2153,31 @@ void AssemblerARM32::vpush(const Variable *OpBaseReg, SizeT NumConsecRegs,
|
| constexpr const char *VpushName = "vpush";
|
| constexpr IValueT VpushOpcode =
|
| B27 | B26 | B24 | B21 | B19 | B18 | B16 | B11 | B9;
|
| - emitVStackOp(Cond, VpushOpcode, OpBaseReg, NumConsecRegs, VpushName);
|
| + emitVStackOp<Form>(Func, Cond, VpushOpcode, OpBaseReg, NumConsecRegs,
|
| + VpushName);
|
| }
|
|
|
| +// Force template instantiations.
|
| +
|
| +template void AssemblerARM32::vpop<TextualAssembly>(const Cfg *Func,
|
| + const Variable *OpBaseReg,
|
| + SizeT NumConsecRegs,
|
| + CondARM32::Cond Cond);
|
| +
|
| +template void AssemblerARM32::vpop<BinaryAssembly>(const Cfg *Func,
|
| + const Variable *OpBaseReg,
|
| + SizeT NumConsecRegs,
|
| + CondARM32::Cond Cond);
|
| +
|
| +template void AssemblerARM32::vpush<TextualAssembly>(const Cfg *Func,
|
| + const Variable *OpBaseReg,
|
| + SizeT NumConsecRegs,
|
| + CondARM32::Cond Cond);
|
| +
|
| +template void AssemblerARM32::vpush<BinaryAssembly>(const Cfg *Func,
|
| + const Variable *OpBaseReg,
|
| + SizeT NumConsecRegs,
|
| + CondARM32::Cond Cond);
|
| +
|
| } // end of namespace ARM32
|
| } // end of namespace Ice
|
|
|