| Index: src/IceInstARM32.cpp
|
| diff --git a/src/IceInstARM32.cpp b/src/IceInstARM32.cpp
|
| index a09c5fcd576b772a6f78be2bebdf23ebaa7b23af..32c5bbd7e9b12d4b91c173924bfdffdd5c763a04 100644
|
| --- a/src/IceInstARM32.cpp
|
| +++ b/src/IceInstARM32.cpp
|
| @@ -87,6 +87,17 @@ CondARM32::Cond InstARM32::getOppositeCondition(CondARM32::Cond Cond) {
|
| return InstARM32CondAttributes[Cond].Opposite;
|
| }
|
|
|
| +template <>
|
| +void InstARM32::startNextAsmInst<TextualAssembly>(const Cfg *Func) const {
|
| + startNextInst(Func);
|
| + Func->getContext()->getStrEmit() << "\n";
|
| +}
|
| +
|
| +template <>
|
| +void InstARM32::startNextAsmInst<BinaryAssembly>(const Cfg *Func) const {
|
| + (void)Func;
|
| +}
|
| +
|
| void InstARM32::startNextInst(const Cfg *Func) const {
|
| if (auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>())
|
| Asm->incEmitTextSize(InstSize);
|
| @@ -1323,67 +1334,10 @@ bool isAssignedConsecutiveRegisters(const Variable *Before,
|
|
|
| } // end of anonymous namespace
|
|
|
| -void InstARM32Pop::emit(const Cfg *Func) const {
|
| - if (!BuildDefs::dump())
|
| - return;
|
| -
|
| - const SizeT DestSize = Dests.size();
|
| - if (DestSize == 0) {
|
| - assert(false && "Empty pop list");
|
| +template <AssemblyOutputForm Form>
|
| +void InstARM32Pop::assemble(const Cfg *Func) const {
|
| + if (Form == TextualAssembly && !BuildDefs::dump())
|
| return;
|
| - }
|
| -
|
| - Ostream &Str = Func->getContext()->getStrEmit();
|
| -
|
| - Variable *Reg = Dests[0];
|
| - if (isScalarIntegerType(Reg->getType())) {
|
| - // GPR push.
|
| - Str << "\t"
|
| - "pop"
|
| - "\t{";
|
| - Reg->emit(Func);
|
| - for (SizeT i = 1; i < DestSize; ++i) {
|
| - Str << ", ";
|
| - Reg = Dests[i];
|
| - Reg->emit(Func);
|
| - }
|
| - Str << "}";
|
| - return;
|
| - }
|
| -
|
| - // VFP "s" reg push.
|
| - SizeT End = DestSize - 1;
|
| - SizeT Start = DestSize - 1;
|
| - Reg = Dests[DestSize - 1];
|
| - Str << "\t"
|
| - "vpop"
|
| - "\t{";
|
| - for (SizeT i = 2; i <= DestSize; ++i) {
|
| - Variable *PreviousReg = Dests[DestSize - i];
|
| - if (!isAssignedConsecutiveRegisters(PreviousReg, Reg)) {
|
| - Dests[Start]->emit(Func);
|
| - for (SizeT j = Start + 1; j <= End; ++j) {
|
| - Str << ", ";
|
| - Dests[j]->emit(Func);
|
| - }
|
| - startNextInst(Func);
|
| - Str << "}\n\t"
|
| - "vpop"
|
| - "\t{";
|
| - End = DestSize - i;
|
| - }
|
| - Reg = PreviousReg;
|
| - Start = DestSize - i;
|
| - }
|
| - Dests[Start]->emit(Func);
|
| - for (SizeT j = Start + 1; j <= End; ++j) {
|
| - Str << ", ";
|
| - Dests[j]->emit(Func);
|
| - }
|
| - Str << "}";
|
| -}
|
| -
|
| -void InstARM32Pop::emitIAS(const Cfg *Func) const {
|
| // Pop can't be emitted if there are no registers to load. This should never
|
| // happen, but if it does, we don't need to bring Subzero down -- we just skip
|
| // emitting the pop instruction (and maybe emit a nop?) The assert() is here
|
| @@ -1393,7 +1347,6 @@ void InstARM32Pop::emitIAS(const Cfg *Func) const {
|
| assert(false && "Empty pop list");
|
| return;
|
| }
|
| -
|
| auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
|
| const auto *Reg = llvm::cast<Variable>(Dests[0]);
|
| if (isScalarIntegerType(Reg->getType())) {
|
| @@ -1415,10 +1368,10 @@ void InstARM32Pop::emitIAS(const Cfg *Func) const {
|
| // Note: Can only apply pop register if single register is not sp.
|
| assert((RegARM32::Encoded_Reg_sp != LastDest->getRegNum()) &&
|
| "Effects of pop register SP is undefined!");
|
| - Asm->pop(LastDest, CondARM32::AL);
|
| + Asm->pop<Form>(Func, LastDest, CondARM32::AL);
|
| break;
|
| default:
|
| - Asm->popList(GPRegisters, CondARM32::AL);
|
| + Asm->popList<Form>(Func, GPRegisters, CondARM32::AL);
|
| break;
|
| }
|
| } else {
|
| @@ -1433,16 +1386,17 @@ void InstARM32Pop::emitIAS(const Cfg *Func) const {
|
| isAssignedConsecutiveRegisters(Reg, NextReg)) {
|
| ++RegCount;
|
| } else {
|
| - Asm->vpop(BaseReg, RegCount, CondARM32::AL);
|
| + Asm->vpop<Form>(Func, BaseReg, RegCount, CondARM32::AL);
|
| + this->startNextAsmInst<Form>(Func);
|
| BaseReg = NextReg;
|
| RegCount = 1;
|
| }
|
| Reg = NextReg;
|
| }
|
| if (RegCount)
|
| - Asm->vpop(BaseReg, RegCount, CondARM32::AL);
|
| + Asm->vpop<Form>(Func, BaseReg, RegCount, CondARM32::AL);
|
| }
|
| - if (Asm->needsTextFixup())
|
| + if (Form == TextualAssembly && Asm->needsTextFixup())
|
| emitUsingTextFixup(Func);
|
| }
|
|
|
| @@ -1459,63 +1413,10 @@ void InstARM32Pop::dump(const Cfg *Func) const {
|
| }
|
| }
|
|
|
| -void InstARM32Push::emit(const Cfg *Func) const {
|
| - if (!BuildDefs::dump())
|
| +template <AssemblyOutputForm Form>
|
| +void InstARM32Push::assemble(const Cfg *Func) const {
|
| + if (Form == TextualAssembly && !BuildDefs::dump())
|
| return;
|
| -
|
| - // Push can't be emitted if there are no registers to save. This should never
|
| - // happen, but if it does, we don't need to bring Subzero down -- we just skip
|
| - // emitting the push instruction (and maybe emit a nop?) The assert() is here
|
| - // so that we can detect this error during development.
|
| - const SizeT SrcSize = getSrcSize();
|
| - if (SrcSize == 0) {
|
| - assert(false && "Empty push list");
|
| - return;
|
| - }
|
| -
|
| - Ostream &Str = Func->getContext()->getStrEmit();
|
| -
|
| - const auto *Reg = llvm::cast<Variable>(getSrc(0));
|
| - if (isScalarIntegerType(Reg->getType())) {
|
| - // GPR push.
|
| - Str << "\t"
|
| - "push"
|
| - "\t{";
|
| - Reg->emit(Func);
|
| - for (SizeT i = 1; i < SrcSize; ++i) {
|
| - Str << ", ";
|
| - getSrc(i)->emit(Func);
|
| - }
|
| - Str << "}";
|
| - return;
|
| - }
|
| -
|
| - // VFP "s" reg push.
|
| - Str << "\t"
|
| - "vpush"
|
| - "\t{";
|
| - Reg->emit(Func);
|
| - SizeT RegCount = 1;
|
| - for (SizeT i = 1; i < SrcSize; ++i) {
|
| - const auto *NextReg = llvm::cast<Variable>(getSrc(i));
|
| - if (RegCount < VpushVpopMaxConsecRegs &&
|
| - isAssignedConsecutiveRegisters(Reg, NextReg)) {
|
| - ++RegCount;
|
| - Str << ", ";
|
| - } else {
|
| - startNextInst(Func);
|
| - RegCount = 1;
|
| - Str << "}\n\t"
|
| - "vpush"
|
| - "\t{";
|
| - }
|
| - Reg = NextReg;
|
| - Reg->emit(Func);
|
| - }
|
| - Str << "}";
|
| -}
|
| -
|
| -void InstARM32Push::emitIAS(const Cfg *Func) const {
|
| // Push can't be emitted if there are no registers to save. This should never
|
| // happen, but if it does, we don't need to bring Subzero down -- we just skip
|
| // emitting the push instruction (and maybe emit a nop?) The assert() is here
|
| @@ -1548,11 +1449,11 @@ void InstARM32Push::emitIAS(const Cfg *Func) const {
|
| // Note: Can only apply push register if single register is not sp.
|
| assert((RegARM32::Encoded_Reg_sp != LastSrc->getRegNum()) &&
|
| "Effects of push register SP is undefined!");
|
| - Asm->push(LastSrc, CondARM32::AL);
|
| + Asm->push<Form>(Func, LastSrc, CondARM32::AL);
|
| break;
|
| }
|
| default:
|
| - Asm->pushList(GPRegisters, CondARM32::AL);
|
| + Asm->pushList<Form>(Func, GPRegisters, CondARM32::AL);
|
| break;
|
| }
|
| } else {
|
| @@ -1565,15 +1466,15 @@ void InstARM32Push::emitIAS(const Cfg *Func) const {
|
| isAssignedConsecutiveRegisters(Reg, NextReg)) {
|
| ++RegCount;
|
| } else {
|
| - Asm->vpush(BaseReg, RegCount, CondARM32::AL);
|
| + Asm->vpush<Form>(Func, BaseReg, RegCount, CondARM32::AL);
|
| BaseReg = NextReg;
|
| RegCount = 1;
|
| }
|
| Reg = NextReg;
|
| }
|
| - Asm->vpush(BaseReg, RegCount, CondARM32::AL);
|
| + Asm->vpush<Form>(Func, BaseReg, RegCount, CondARM32::AL);
|
| }
|
| - if (Asm->needsTextFixup())
|
| + if (Form == TextualAssembly && Asm->needsTextFixup())
|
| emitUsingTextFixup(Func);
|
| }
|
|
|
|
|