[PATCH] D14390: [mips] Expansion of LI.S and LI.D
Simon Dardis via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 3 04:26:20 PDT 2016
sdardis added inline comments.
================
Comment at: lib/Target/Mips/AsmParser/MipsAsmParser.cpp:2769
+ case Mips::RA: return Mips::ZERO;
+ default: return 0;
+ }
----------------
Two things:
This function also needs to handle floating point registers.
Rather than returning 0, instead call llvm_unreachable("Unknown register in assembly macro expansion!");
================
Comment at: lib/Target/Mips/AsmParser/MipsAsmParser.cpp:2929
+
+ if (LoImmOp64 == 0) {
+ unsigned ATReg = getATReg(IDLoc);
----------------
This block has the wrong condition. This should check that the lower 32 bits are zero and the high part can be loaded with a single instruction.
================
Comment at: lib/Target/Mips/AsmParser/MipsAsmParser.cpp:2931-2936
+ if (!ATReg)
+ return true;
+ if (!Is64FPU) {
+ if (loadImmediate(HiImmOp64, ATReg, Mips::NoRegister, true, true, IDLoc,
+ Out, STI))
+ return true;
----------------
Add a FIXME comment here noting that in the case where the constant is zero, we can load the register directly from the zero register.
================
Comment at: lib/Target/Mips/AsmParser/MipsAsmParser.cpp:2933
+ return true;
+ if (!Is64FPU) {
+ if (loadImmediate(HiImmOp64, ATReg, Mips::NoRegister, true, true, IDLoc,
----------------
This condition is not required.
================
Comment at: lib/Target/Mips/AsmParser/MipsAsmParser.cpp:2937
+ return true;
+ if(hasMips32r2()) {
+ TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, ATReg, IDLoc, STI);
----------------
This also needs a check for hasMips64() before checking hasMips32r2(). In the mips64 case, we use dmtc1.
================
Comment at: lib/Target/Mips/AsmParser/MipsAsmParser.cpp:2938-2939
+ if(hasMips32r2()) {
+ TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, ATReg, IDLoc, STI);
+ TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
+ } else {
----------------
If you've reverse engineered this from the output of gas, you've hit upon a latent gas bug.
On a MIPS32 system (or a MIPS64 system executing MIPS32 code) , writing to a 64 bit FPU register must be done in a specific order; use mtc1 to write the lower 32bits, then use mthc1 to write the upper 32 bits. mtcX instructions leave the upper 32bits *UNPREDICTABLE*.
Reverse the order of these two lines.
================
Comment at: lib/Target/Mips/AsmParser/MipsAsmParser.cpp:2941-2942
+ } else {
+ TOut.emitRR(Mips::MTC1, nextReg(FirstReg), ATReg, IDLoc, STI);
+ TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
+ }
----------------
See my comment about nextReg.
Also, indentation is incorrect.
================
Comment at: lib/Target/Mips/AsmParser/MipsAsmParser.cpp:2979-2980
+
+ TOut.emitRRX(Mips::LDC1, FirstReg, Mips::GP,
+ MCOperand::createExpr(FixupAddr), IDLoc, STI);
+ }
----------------
Rather than Mips::LDC1, this should be (IsFPU64 ? Mips::LDC164 : Mips::LDC1) to get the correct instruction.
Add a FIXME comment here noting that this expansion is incorrect for mips1, it should expand to two word loads.
================
Comment at: test/MC/Mips/macro-li.d.s:1
+# RUN: llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r2 -show-encoding | FileCheck %s --check-prefix=CHECK-MIPS32
+# RUN: llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips64r2 -show-encoding | FileCheck %s --check-prefix=CHECK-MIPS64
----------------
Can you also a RUN line for mips32 and add appropriate tests?
https://reviews.llvm.org/D14390
More information about the llvm-commits
mailing list