Disassembler support allows for 'round-trip' testing, and rv32i-valid.s has been updated appropriately.
Details
Diff Detail
Event Timeline
lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp | ||
---|---|---|
45 | Style: Should these be in a header somewhere? | |
64 | Can this static cast be lifted through the call chain to the entry point? Or are each of these used directly from table gen? This is more than a bit messy and concerning. | |
72 | style: Is there a RegClass.max like value we could use here instead? | |
90 | Not quite sure what we're going for here, but sign extending an unsigned immediate seems a bit odd. Possibly a clarifying comment? | |
102 | Style: move this below the early return. | |
lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp | ||
106 | We need to assert the size of the immediate don't we? Also, didn't we have a checked cast function in one of the previous patches already? | |
108 | Why the assert immediately followed by an unreachable | |
lib/Target/RISCV/RISCVInstrFormats.td | ||
31 | What is this? I don't see it being used anywhere in this patch? |
Refresh to reflect change made in previous patches in the series, and address review comments from @reames.
lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp | ||
---|---|---|
45 | Actually this is redundant as they're already in RISCVMCTargetDesc.h which is already include - removed. Thanks! | |
64 | I've lifted the cast to DecodeGPRRegisterClass, which is the entry-point from TableGen generated code, and in the end got rid of getReg entirely. | |
90 | The immediate value is extracted from the instruction and passed as a uint64_t. The assert checks that it the bitwidth is as we expect, but we can sign-extend it from the appropriate bit position. SignExtend64 is written for this exact purpose (sign extends the bottom N bits of the uint64_t that it is passed). I've added a comment to clarify what is going on that hopefully makes it easier to follow? I've also added a comment in the new decodeSImmOperandAndLsl1 which is perhaps even more confusing. Do let me know any suggestions for making it clearer. | |
lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp | ||
106 | I've now defined getImmOpValue rather than first defining getImm20OpValue only to change things in the next patch. | |
lib/Target/RISCV/RISCVInstrFormats.td | ||
31 | Tablegenning the disassembler fails without it. I've stolen an explanatory comment from the AMDGPU backend: // SoftFail is a field the disassembler can use to provide a way for // instructions to not match without killing the whole decode process. It is // mainly used for ARM, but Tablegen expects this field to exist or it fails // to build the decode table. |
lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp | ||
---|---|---|
112 | RISC-VC? |
test/MC/RISCV/rv32i-valid.s | ||
---|---|---|
3 | Using the same file to test both directions seems like a nice method -- but strangely, almost unique amongst the tests for the backends. I actually especially like the way it's done in test/MC/X86/mpx-encodings.s, where it uses the same CHECK: line for both the asm output of llvm-mc, and the output of llvm-objdump. I'd suggest doing it that way, which would nicely resolve my comment in D23564 too. |
Tests now check both assembly printing and disassembly. I've added a comment/TODO regarding decode of instructions outside of the RV32/RV64 core that might be 16-bit, 48bit, 64bit, ...
Refresh to follow changes made in rL283702, putting TheRISCV32Target and TheRISCV64Target behind accessors.
The previous version of this patch made the mistake when decoding a GPR of assuming you can use the parsed RegNo as an index into the register class. In the general case, a register class will have the registers in preferred allocation order, meaning this will fail. Instead, we have a GPRDecoderTable to select the appropriate register based on the parsed RegNo.
Style: Should these be in a header somewhere?