Changeset View
Standalone View
lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Show First 20 Lines • Show All 230 Lines • ▼ Show 20 Lines | #include "MipsGenAsmMatcher.inc" | ||||
bool expandDRotation(MCInst &Inst, SMLoc IDLoc, | bool expandDRotation(MCInst &Inst, SMLoc IDLoc, | ||||
SmallVectorImpl<MCInst> &Instructions); | SmallVectorImpl<MCInst> &Instructions); | ||||
bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, | bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, | ||||
SmallVectorImpl<MCInst> &Instructions); | SmallVectorImpl<MCInst> &Instructions); | ||||
bool expandAbs(MCInst &Inst, SMLoc IDLoc, | bool expandAbs(MCInst &Inst, SMLoc IDLoc, | ||||
SmallVectorImpl<MCInst> &Instructions); | SmallVectorImpl<MCInst> &Instructions); | ||||
bool expandMulImm(MCInst &Inst, SMLoc IDLoc, | |||||
SmallVectorImpl<MCInst> &Instructions); | |||||
bool expandMulO(MCInst &Inst, SMLoc IDLoc, | |||||
SmallVectorImpl<MCInst> &Instructions); | |||||
bool expandMulOU(MCInst &Inst, SMLoc IDLoc, | |||||
SmallVectorImpl<MCInst> &Instructions); | |||||
void createNop(bool hasShortDelaySlot, SMLoc IDLoc, | void createNop(bool hasShortDelaySlot, SMLoc IDLoc, | ||||
SmallVectorImpl<MCInst> &Instructions); | SmallVectorImpl<MCInst> &Instructions); | ||||
void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg, | void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg, | ||||
bool Is64Bit, SmallVectorImpl<MCInst> &Instructions); | bool Is64Bit, SmallVectorImpl<MCInst> &Instructions); | ||||
void createCpRestoreMemOp(bool IsLoad, int StackOffset, SMLoc IDLoc, | void createCpRestoreMemOp(bool IsLoad, int StackOffset, SMLoc IDLoc, | ||||
SmallVectorImpl<MCInst> &Instructions); | SmallVectorImpl<MCInst> &Instructions); | ||||
▲ Show 20 Lines • Show All 1,841 Lines • ▼ Show 20 Lines | return expandDRotation(Inst, IDLoc, Instructions) ? MER_Fail | ||||
: MER_Success; | : MER_Success; | ||||
case Mips::DROLImm: | case Mips::DROLImm: | ||||
case Mips::DRORImm: | case Mips::DRORImm: | ||||
return expandDRotationImm(Inst, IDLoc, Instructions) ? MER_Fail | return expandDRotationImm(Inst, IDLoc, Instructions) ? MER_Fail | ||||
: MER_Success; | : MER_Success; | ||||
case Mips::ABSMacro: | case Mips::ABSMacro: | ||||
return expandAbs(Inst, IDLoc, Instructions) ? MER_Fail | return expandAbs(Inst, IDLoc, Instructions) ? MER_Fail | ||||
: MER_Success; | : MER_Success; | ||||
case Mips::MULImm: | |||||
case Mips::DMULImm: | |||||
return expandMulImm(Inst, IDLoc, Instructions) ? MER_Fail | |||||
: MER_Success; | |||||
case Mips::MULO: | |||||
case Mips::DMULO: | |||||
return expandMulO(Inst, IDLoc, Instructions) ? MER_Fail | |||||
: MER_Success; | |||||
case Mips::MULOU: | |||||
case Mips::DMULOU: | |||||
return expandMulOU(Inst, IDLoc, Instructions) ? MER_Fail | |||||
: MER_Success; | |||||
} | } | ||||
} | } | ||||
bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, | bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, | ||||
SmallVectorImpl<MCInst> &Instructions) { | SmallVectorImpl<MCInst> &Instructions) { | ||||
// Create a JALR instruction which is going to replace the pseudo-JAL. | // Create a JALR instruction which is going to replace the pseudo-JAL. | ||||
MCInst JalrInst; | MCInst JalrInst; | ||||
JalrInst.setLoc(IDLoc); | JalrInst.setLoc(IDLoc); | ||||
▲ Show 20 Lines • Show All 1,444 Lines • ▼ Show 20 Lines | if (FirstRegOp != SecondRegOp) | ||||
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, Instructions); | emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, Instructions); | ||||
else | else | ||||
createNop(false, IDLoc, Instructions); | createNop(false, IDLoc, Instructions); | ||||
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, Instructions); | emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, Instructions); | ||||
return false; | return false; | ||||
} | } | ||||
bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, | |||||
SmallVectorImpl<MCInst> &Instructions) { | |||||
unsigned ATReg = Mips::NoRegister; | |||||
unsigned DReg = Inst.getOperand(0).getReg(); | |||||
unsigned SReg = Inst.getOperand(1).getReg(); | |||||
int32_t ImmValue = Inst.getOperand(2).getImm(); | |||||
ATReg = getATReg(Inst.getLoc()); | |||||
if (!ATReg) | |||||
return true; | |||||
loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, Inst.getLoc(), Instructions); | |||||
if (Inst.getOpcode() == Mips::MULImm) | |||||
emitRR(Mips::MULT, SReg, ATReg, IDLoc, Instructions); | |||||
else | |||||
emitRR(Mips::DMULT, SReg, ATReg, IDLoc, Instructions); | |||||
dsanders: Use the ternary operator | |||||
Sorry, this isn't quite what I meant. I should have been clearer. Rather than a ternary operator with assignments inside it, I was looking for something like: emitRR(Inst.getOpcode() == Mips::MULImm ? Mips::MULT : Mips::DMULT, SReg, ATReg, IDLoc, Instructions); dsanders: Sorry, this isn't quite what I meant. I should have been clearer.
Rather than a ternary… | |||||
emitR(Mips::MFLO, DReg, IDLoc, Instructions); | |||||
return false; | |||||
} | |||||
bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, | |||||
SmallVectorImpl<MCInst> &Instructions) { | |||||
unsigned ATReg = Mips::NoRegister; | |||||
unsigned DReg = Inst.getOperand(0).getReg(); | |||||
unsigned SReg = Inst.getOperand(1).getReg(); | |||||
unsigned TReg = Inst.getOperand(2).getReg(); | |||||
ATReg = getATReg(Inst.getLoc()); | |||||
if (!ATReg) | |||||
return true; | |||||
if (Inst.getOpcode() == Mips::MULO) | |||||
emitRR(Mips::MULT, SReg, TReg, IDLoc, Instructions); | |||||
else | |||||
emitRR(Mips::DMULT, SReg, TReg, IDLoc, Instructions); | |||||
dsandersUnsubmitted Likewise dsanders: Likewise | |||||
As above, this isn't quite what I meant. dsanders: As above, this isn't quite what I meant. | |||||
emitR(Mips::MFLO, DReg, IDLoc, Instructions); | |||||
if (Inst.getOpcode() == Mips::MULO) | |||||
emitRRI(Mips::SRA, DReg, DReg, 0x1F, IDLoc, Instructions); | |||||
else | |||||
emitRRI(Mips::DSRA32, DReg, DReg, 0x1F, IDLoc, Instructions); | |||||
dsandersUnsubmitted Likewise dsanders: Likewise | |||||
As above, this isn't quite what I meant. dsanders: As above, this isn't quite what I meant. | |||||
emitR(Mips::MFHI, ATReg, IDLoc, Instructions); | |||||
emitRRI(Mips::BEQ, DReg, ATReg, 8, IDLoc, Instructions); | |||||
if (AssemblerOptions.back()->isReorder()) | |||||
createNop(false, IDLoc, Instructions); | |||||
emitII(Mips::BREAK,6, 0, IDLoc, Instructions); | |||||
dsandersUnsubmitted What happens when useTraps() is true? Shouldn't this use a trap instruction instead of a break dsanders: What happens when useTraps() is true? Shouldn't this use a trap instruction instead of a break | |||||
emitR(Mips::MFLO, DReg, IDLoc, Instructions); | |||||
Not Done ReplyInline ActionsI've just noticed that this isn't going to work for micromips because the offset is likely to be different for that case. If it's a constant offset then we can work around it for now (and leave a FIXME) but if it's variable then we'll need to find some way to do this. For reference, my overall plan for solving this kind of problem is to finish rewriting the emit*() functions such that they directly write to the target streamer. This allows us to drop labels wherever we need them using the target streamer methods. dsanders: I've just noticed that this isn't going to work for micromips because the offset is likely to… | |||||
Not Done ReplyInline ActionsIt is unclear to me what do you suggest regarding micromips potential problem with branch offset. Please be more precise. obucina: It is unclear to me what do you suggest regarding micromips potential problem with branch… | |||||
The offset needs to be different for microMIPS so you need to test for microMIPS and select between the MIPS and microMIPS value. If the offset for the microMIPS case is a constant then we can use magic numbers for the moment (but please document them with comments). If the offset for the microMIPS case is variable for any reason then we'll have to find some way to account for the variability somehow (which could require the work explained at the bottom of this comment). Ideally, we'd avoid any magic numbers using symbols and symbol references but it's not possible to do that right now (see below)
The reason we can't use symbols to avoid magic numbers at the moment is because this migration work is not yet complete. The problem is that we collect the expansion in a list of instructions and we can't put symbol definitions in this list. To eliminate the magic numbers we need to finish this work and use the target streamers as a stream. This will allow us to drop temporary symbols wherever we need them. dsanders: The offset needs to be different for microMIPS so you need to test for microMIPS and select… | |||||
return false; | |||||
} | |||||
bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, | |||||
SmallVectorImpl<MCInst> &Instructions) { | |||||
unsigned ATReg = Mips::NoRegister; | |||||
unsigned DReg = Inst.getOperand(0).getReg(); | |||||
unsigned SReg = Inst.getOperand(1).getReg(); | |||||
unsigned TReg = Inst.getOperand(2).getReg(); | |||||
ATReg = getATReg(Inst.getLoc()); | |||||
if (!ATReg) | |||||
return true; | |||||
if (Inst.getOpcode() == Mips::MULOU) | |||||
emitRR(Mips::MULTu, SReg, TReg, IDLoc, Instructions); | |||||
else | |||||
emitRR(Mips::DMULTu, SReg, TReg, IDLoc, Instructions); | |||||
dsandersUnsubmitted Use ternary operator dsanders: Use ternary operator | |||||
As above, this isn't quite what I meant. dsanders: As above, this isn't quite what I meant. | |||||
emitR(Mips::MFHI, ATReg, IDLoc, Instructions); | |||||
emitR(Mips::MFLO, DReg, IDLoc, Instructions); | |||||
emitRRI(Mips::BEQ, ATReg, Mips::ZERO, 8, IDLoc, Instructions); | |||||
if (AssemblerOptions.back()->isReorder()) | |||||
createNop(false, IDLoc, Instructions); | |||||
emitII(Mips::BREAK, 6, 0, IDLoc, Instructions); | |||||
dsandersUnsubmitted What happens when useTraps() is true? Shouldn't this use a trap instruction instead of a break dsanders: What happens when useTraps() is true? Shouldn't this use a trap instruction instead of a break | |||||
return false; | |||||
} | |||||
void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc, | void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc, | ||||
SmallVectorImpl<MCInst> &Instructions) { | SmallVectorImpl<MCInst> &Instructions) { | ||||
if (hasShortDelaySlot) | if (hasShortDelaySlot) | ||||
Similar to expandMulO(), this constant is different on micromips and might not be a constant. dsanders: Similar to expandMulO(), this constant is different on micromips and might not be a constant. | |||||
Not Done ReplyInline ActionsIt is unclear to me what do you suggest regarding micromips potential problem with branch offset. Please be more precise. obucina: It is unclear to me what do you suggest regarding micromips potential problem with branch… | |||||
emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Instructions); | emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Instructions); | ||||
else | else | ||||
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Instructions); | emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Instructions); | ||||
} | } | ||||
void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg, | void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg, | ||||
unsigned TrgReg, bool Is64Bit, | unsigned TrgReg, bool Is64Bit, | ||||
SmallVectorImpl<MCInst> &Instructions) { | SmallVectorImpl<MCInst> &Instructions) { | ||||
emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(), | emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(), | ||||
Instructions); | Instructions); | ||||
Indentation dsanders: Indentation | |||||
} | } | ||||
void MipsAsmParser::createCpRestoreMemOp( | void MipsAsmParser::createCpRestoreMemOp( | ||||
bool IsLoad, int StackOffset, SMLoc IDLoc, | bool IsLoad, int StackOffset, SMLoc IDLoc, | ||||
SmallVectorImpl<MCInst> &Instructions) { | SmallVectorImpl<MCInst> &Instructions) { | ||||
// If the offset can not fit into 16 bits, we need to expand. | // If the offset can not fit into 16 bits, we need to expand. | ||||
if (!isInt<16>(StackOffset)) { | if (!isInt<16>(StackOffset)) { | ||||
MCInst MemInst; | MCInst MemInst; | ||||
▲ Show 20 Lines • Show All 2,660 Lines • Show Last 20 Lines |
Use the ternary operator