|
|
|
|
@ -2,6 +2,7 @@
|
|
|
|
|
|
|
|
|
|
#include <stdexcept>
|
|
|
|
|
#include <unordered_map>
|
|
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
|
|
#include "ir/IR.h"
|
|
|
|
|
#include "utils/Log.h"
|
|
|
|
|
@ -20,6 +21,12 @@ namespace {
|
|
|
|
|
|
|
|
|
|
using ValueSlotMap = std::unordered_map<const ir::Value*, int>;
|
|
|
|
|
|
|
|
|
|
static uint32_t FloatToBits(float f) {
|
|
|
|
|
uint32_t bits;
|
|
|
|
|
memcpy(&bits, &f, sizeof(bits));
|
|
|
|
|
return bits;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取类型大小(字节)
|
|
|
|
|
int GetTypeSize(const ir::Type* type) {
|
|
|
|
|
if (!type) return 4;
|
|
|
|
|
@ -109,15 +116,23 @@ void EmitValueToReg(const ir::Value* value, PhysReg target,
|
|
|
|
|
}
|
|
|
|
|
// 处理浮点常量
|
|
|
|
|
if (auto* fconstant = dynamic_cast<const ir::ConstantFloat*>(value)) {
|
|
|
|
|
// 浮点常量需要先存储到栈槽,再加载到寄存器
|
|
|
|
|
// 因为 ARMv8 没有直接加载浮点立即数的指令
|
|
|
|
|
int slot = -1;
|
|
|
|
|
// 注意:这里需要找到或创建该浮点常量的栈槽
|
|
|
|
|
// 简单起见,可以每次都分配新栈槽
|
|
|
|
|
// 更好的做法是:在 Module 级别缓存浮点常量
|
|
|
|
|
throw std::runtime_error(
|
|
|
|
|
FormatError("mir", "浮点常量暂未实现"));
|
|
|
|
|
return;
|
|
|
|
|
// 浮点常量需要存储到栈槽,然后加载到寄存器
|
|
|
|
|
// 检查是否已经为这个常量分配了栈槽
|
|
|
|
|
auto it = slots.find(value);
|
|
|
|
|
int slot;
|
|
|
|
|
if (it == slots.end()) {
|
|
|
|
|
// 分配新的栈槽
|
|
|
|
|
slot = function.CreateFrameIndex(4);
|
|
|
|
|
// 将浮点常量存储到栈槽
|
|
|
|
|
float fval = fconstant->GetValue();
|
|
|
|
|
// 将浮点数作为立即数加载(使用整数表示)
|
|
|
|
|
uint32_t int_val = *reinterpret_cast<uint32_t*>(&fval);
|
|
|
|
|
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(static_cast<int>(int_val))});
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(slot)});
|
|
|
|
|
const_cast<ValueSlotMap&>(slots).emplace(value, slot);
|
|
|
|
|
} else {
|
|
|
|
|
slot = it->second;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 处理零常量
|
|
|
|
|
if (dynamic_cast<const ir::ConstantZero*>(value) ||
|
|
|
|
|
|