Changeset View
Standalone View
lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Show First 20 Lines • Show All 235 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); | |||||
bool expandDMULMacro(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,863 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::MULImmMacro: | |||||
case Mips::DMULImmMacro: | |||||
return expandMulImm(Inst, IDLoc, Instructions) ? MER_Fail | |||||
: MER_Success; | |||||
case Mips::MULOMacro: | |||||
case Mips::DMULOMacro: | |||||
return expandMulO(Inst, IDLoc, Instructions) ? MER_Fail | |||||
: MER_Success; | |||||
case Mips::MULOUMacro: | |||||
case Mips::DMULOUMacro: | |||||
return expandMulOU(Inst, IDLoc, Instructions) ? MER_Fail | |||||
: MER_Success; | |||||
case Mips::DMULMacro: | |||||
return expandDMULMacro(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,480 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); | |||||
emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : 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; | |||||
emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT, | |||||
SReg, TReg, IDLoc, Instructions); | |||||
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); | |||||
emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32, | |||||
DReg, DReg, 0x1F, IDLoc, Instructions); | |||||
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); | |||||
if (useTraps()) { | |||||
emitRRI(Mips::TNE, DReg, ATReg, 6, IDLoc, Instructions); | |||||
} else { | |||||
emitRRI(Mips::BEQ, DReg, ATReg, 8, IDLoc, Instructions); | |||||
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 | |||||
if (AssemblerOptions.back()->isReorder()) | |||||
createNop(false, 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… | |||||
obucinaUnsubmitted 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… | |||||
dsandersUnsubmitted 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… | |||||
emitII(Mips::BREAK,6, 0, IDLoc, Instructions); | |||||
} | |||||
emitR(Mips::MFLO, DReg, IDLoc, Instructions); | |||||
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; | |||||
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. | |||||
emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu, | |||||
SReg, TReg, IDLoc, Instructions); | |||||
emitR(Mips::MFHI, ATReg, IDLoc, Instructions); | |||||
emitR(Mips::MFLO, DReg, IDLoc, Instructions); | |||||
if (useTraps()) { | |||||
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 | |||||
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, Instructions); | |||||
} else { | |||||
emitRRI(Mips::BEQ, ATReg, Mips::ZERO, 8, IDLoc, Instructions); | |||||
if (AssemblerOptions.back()->isReorder()) | |||||
createNop(false, IDLoc, Instructions); | |||||
emitII(Mips::BREAK, 6, 0, IDLoc, Instructions); | |||||
} | |||||
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. | |||||
obucinaUnsubmitted 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… | |||||
return false; | |||||
} | |||||
bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, | |||||
SmallVectorImpl<MCInst> &Instructions) { | |||||
unsigned DReg = Inst.getOperand(0).getReg(); | |||||
unsigned SReg = Inst.getOperand(1).getReg(); | |||||
unsigned TReg = Inst.getOperand(2).getReg(); | |||||
Indentation dsanders: Indentation | |||||
emitRR(Mips::DMULTu, SReg, TReg, IDLoc, Instructions); | |||||
emitR(Mips::MFLO, DReg, IDLoc, Instructions); | |||||
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) | ||||
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); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 2,727 Lines • Show Last 20 Lines |
Use the ternary operator