The patch implements microMIPSr6 LWXS, LWP and SWP instructions.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
lib/Target/Mips/AsmParser/MipsAsmParser.cpp | ||
---|---|---|
3449–3454 ↗ | (On Diff #28209) | While this looks like a sensible thing to do I'm afraid this isn't correct. The problems it causes will be very subtle and might not reveal themselves for a long time. It's not a parse failure to let non-GPR's through here, we just have to catch them during matching using predicates instead. The root of the problem is that all parsing decisions are final since there is no backtracking. Making matching decisions during the parse can can cause erratic behaviour that depends on the order of the matcher table. About a year ago, this became apparent when the parser was selecting FPU register classes at parse time. As a result, the matcher was failing to match legitimate code because the parser had made the wrong decision, blocking the possibility of matching the correct instruction. This is also why numeric registers aren't resolved to a register class until the moment they are rendered into an instruction. If we decided earlier, then an incorrect decision would prevent the assembler matching valid instructions. |
lib/Target/Mips/Disassembler/MipsDisassembler.cpp | ||
1326–1328 ↗ | (On Diff #28209) | Nit: LLVM convention is operators on the previous line like so: if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM || Inst.getOpcode() == Mips::LWP_MMR6 || Inst.getOpcode() == Mips::SWP_MMR6) |
lib/Target/Mips/MicroMips32r6InstrFormats.td | ||
252–254 ↗ | (On Diff #28209) | Please extract the two pieces of addr to separate fields as per CACHE_PREF_FM_MM. It serves to explain the unusual encoding. |
lib/Target/Mips/MicroMips32r6InstrInfo.td | ||
250–261 ↗ | (On Diff #28209) | LWXS was removed in microMIPSr6 |
263–292 ↗ | (On Diff #28209) | Possible Nit: There's no need for a separate *_DESC_BASE if there's only one *_DESC inheriting from it. Are there more instructions on the way that will use these *_DESC_BASE's? |
Used predicate method for regpair operand check instead of additional lines of code in parseRegisterPair method.
Extracted two pieces of addr to separate fields in LWM_FM_MMR6 class.
Removed implementation of LWXS instruction.
Removed separate _DESC_BASE classes.
lib/Target/Mips/AsmParser/MipsAsmParser.cpp | ||
---|---|---|
3449–3454 ↗ | (On Diff #28209) | This update is closer and fixes the subtle bugs but is still making the key mistake described in my previous comment. You're trying to convert to a internal register number too early. You need to remove RegIdxOp::ParsedRegNum and the related changes and leave the conversion to an internal register number to the render method (addRegPairOperand()). The reason this render method doesn't work at the moment is that it's trying to use an index as a register number. It's missing the call to getGPR32Reg() that other renderers like addGPR32AsmRegOperands() have. |
947 ↗ | (On Diff #29878) | LLVM convention is operators on the previous line |
1013 ↗ | (On Diff #29878) | You want to test RegIdxOp::Index rather than ParsedRegNum (0-31 contains NoRegister, DSPCCond, MSACSR, and AT_64, among others). Also, I think it should be '30' instead of '31' since register pairs consist of Index and Index+1 |
lib/Target/Mips/Disassembler/MipsDisassembler.cpp | ||
1331–1333 ↗ | (On Diff #29878) | This hasn't been fixed. |
lib/Target/Mips/MicroMips32r6InstrFormats.td | ||
252–254 ↗ | (On Diff #29878) | Done |
lib/Target/Mips/MicroMips32r6InstrInfo.td | ||
259–270 ↗ | (On Diff #29878) | Done |
272–301 ↗ | (On Diff #29878) | Done |
Removed RegIdxOp::ParsedRegNum.
Added test to RegIdxOp::Index in isRegPair() method.
Conversion to an internal register number is placed in addRegPairOperands() method.
This patch looks mostly correct to me except it's missing a key issue, that for lwp rd and base cannot be the same. lwp is not guaranteed to be uninterruptible so an interrupt could render lwp not restartable if they are the same.
Fortunately we already have an similar example with jalr.hb. You need to extend MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) on line 3668 to account for this context sensitive predicate.
Rebased to work with TOT.
Added check for Rd and Base registers of LWP to MipsAsmParser::checkTargetMatchPredicate method.
Added invalid test for the case of same Rd and Base registers of LWP instruction.
Renamed mem_simm12gpr to mem_simm12 and added DiagnosticType "MemSImm12" to MipsMemSimm12AsmOperand class.
Added selection of proper register class (32/64-bit) to addRegPairOperands method (MipsAsmParser.cpp).
LGTM, for the error messages that are incorrect, can you copy the FIXME I've mentioned in inline comments?
test/MC/Mips/micromips/invalid.s | ||
---|---|---|
61 ↗ | (On Diff #55537) | This is a wrong error message. 8 falls within the range of a 12-bit signed offset. Can you copy the FIXME from micromips32r6/invalid.s below swe here? |
test/MC/Mips/micromips32r6/invalid.s | ||
155–159 ↗ | (On Diff #55537) | See my comment above. |
test/MC/Mips/micromips64r6/invalid.s | ||
184 ↗ | (On Diff #55537) | See my comment above about the wrong error message. |