Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kateinoigakukun/75ddbc8c2b6e1c56860f22a222a6e85a to your computer and use it in GitHub Desktop.
Save kateinoigakukun/75ddbc8c2b6e1c56860f22a222a6e85a to your computer and use it in GitHub Desktop.
diff --git a/llvm/include/llvm/MC/MCInst.h b/llvm/include/llvm/MC/MCInst.h
index 360dbda58fcb..50f847456c28 100644
--- a/llvm/include/llvm/MC/MCInst.h
+++ b/llvm/include/llvm/MC/MCInst.h
@@ -36,6 +36,7 @@ class MCOperand {
kInvalid, ///< Uninitialized.
kRegister, ///< Register operand.
kImmediate, ///< Immediate operand.
+ kSFPImmediate, ///< Single-floating-point immediate operand.
kFPImmediate, ///< Floating-point immediate operand.
kExpr, ///< Relocatable immediate operand.
kInst ///< Sub-instruction operand.
@@ -45,6 +46,7 @@ class MCOperand {
union {
unsigned RegVal;
int64_t ImmVal;
+ float SFPImmVal;
double FPImmVal;
const MCExpr *ExprVal;
const MCInst *InstVal;
@@ -56,6 +58,7 @@ public:
bool isValid() const { return Kind != kInvalid; }
bool isReg() const { return Kind == kRegister; }
bool isImm() const { return Kind == kImmediate; }
+ bool isSFPImm() const { return Kind == kSFPImmediate; }
bool isFPImm() const { return Kind == kFPImmediate; }
bool isExpr() const { return Kind == kExpr; }
bool isInst() const { return Kind == kInst; }
@@ -82,6 +85,16 @@ public:
ImmVal = Val;
}
+ float getSFPImm() const {
+ assert(isSFPImm() && "This is not an SFP immediate");
+ return SFPImmVal;
+ }
+
+ void setSFPImm(float Val) {
+ assert(isSFPImm() && "This is not an SFP immediate");
+ SFPImmVal = Val;
+ }
+
double getFPImm() const {
assert(isFPImm() && "This is not an FP immediate");
return FPImmVal;
@@ -126,6 +139,13 @@ public:
return Op;
}
+ static MCOperand createSFPImm(float Val) {
+ MCOperand Op;
+ Op.Kind = kSFPImmediate;
+ Op.SFPImmVal = Val;
+ return Op;
+ }
+
static MCOperand createFPImm(double Val) {
MCOperand Op;
Op.Kind = kFPImmediate;
diff --git a/llvm/include/llvm/MC/MCInstBuilder.h b/llvm/include/llvm/MC/MCInstBuilder.h
index 0c8e01fdc412..f2986d6f2f5b 100644
--- a/llvm/include/llvm/MC/MCInstBuilder.h
+++ b/llvm/include/llvm/MC/MCInstBuilder.h
@@ -39,6 +39,12 @@ public:
return *this;
}
+ /// Add a new floating point immediate operand.
+ MCInstBuilder &addSFPImm(float Val) {
+ Inst.addOperand(MCOperand::createSFPImm(Val));
+ return *this;
+ }
+
/// Add a new floating point immediate operand.
MCInstBuilder &addFPImm(double Val) {
Inst.addOperand(MCOperand::createFPImm(Val));
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
index d0e9eb1fc9bc..41b2a29aaaf3 100644
--- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
+++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
@@ -126,7 +126,7 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
void addFPImmOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
if (Kind == Float)
- Inst.addOperand(MCOperand::createFPImm(Flt.Val));
+ Inst.addOperand(MCOperand::createSFPImm(Flt.Val));
else
llvm_unreachable("Should be float immediate!");
}
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
index f60b5fcd14ec..4367fea5ce8d 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
@@ -240,9 +240,7 @@ void WebAssemblyInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
const MCInstrDesc &Desc = MII.get(MI->getOpcode());
const MCOperandInfo &Info = Desc.OpInfo[OpNo];
if (Info.OperandType == WebAssembly::OPERAND_F32IMM) {
- // TODO: MC converts all floating point immediate operands to double.
- // This is fine for numeric values, but may cause NaNs to change bits.
- O << ::toString(APFloat(float(Op.getFPImm())));
+ O << ::toString(APFloat(Op.getSFPImm()));
} else {
assert(Info.OperandType == WebAssembly::OPERAND_F64IMM);
O << ::toString(APFloat(Op.getFPImm()));
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
index 1a4c57e66d2f..4148a5432dcd 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
@@ -128,9 +128,7 @@ void WebAssemblyMCCodeEmitter::encodeInstruction(
} else if (MO.isFPImm()) {
const MCOperandInfo &Info = Desc.OpInfo[I];
if (Info.OperandType == WebAssembly::OPERAND_F32IMM) {
- // TODO: MC converts all floating point immediate operands to double.
- // This is fine for numeric values, but may cause NaNs to change bits.
- auto F = float(MO.getFPImm());
+ auto F = MO.getSFPImm();
support::endian::write<float>(OS, F, support::little);
} else {
assert(Info.OperandType == WebAssembly::OPERAND_F64IMM);
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
index 07f183c0e1a1..a00323bc7bb9 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
@@ -275,11 +275,9 @@ void WebAssemblyMCInstLower::lower(const MachineInstr *MI,
break;
}
case MachineOperand::MO_FPImmediate: {
- // TODO: MC converts all floating point immediate operands to double.
- // This is fine for numeric values, but may cause NaNs to change bits.
const ConstantFP *Imm = MO.getFPImm();
if (Imm->getType()->isFloatTy())
- MCOp = MCOperand::createFPImm(Imm->getValueAPF().convertToFloat());
+ MCOp = MCOperand::createSFPImm(Imm->getValueAPF().convertToFloat());
else if (Imm->getType()->isDoubleTy())
MCOp = MCOperand::createFPImm(Imm->getValueAPF().convertToDouble());
else
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment