|
|
|
|
@ -21,6 +21,10 @@ namespace {
|
|
|
|
|
|
|
|
|
|
using ValueSlotMap = std::unordered_map<const ir::Value*, int>;
|
|
|
|
|
|
|
|
|
|
inline bool IsInt32Type(const ir::Type* type) {
|
|
|
|
|
return type && type->IsInt32() && type->Size() == 4;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint32_t FloatToBits(float f) {
|
|
|
|
|
uint32_t bits;
|
|
|
|
|
memcpy(&bits, &f, sizeof(bits));
|
|
|
|
|
@ -364,83 +368,224 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
auto& bin = static_cast<const ir::BinaryInst&>(inst);
|
|
|
|
|
const ir::Type* lhsTy = bin.GetLhs()->GetType().get();
|
|
|
|
|
const ir::Type* rhsTy = bin.GetRhs()->GetType().get();
|
|
|
|
|
|
|
|
|
|
const ir::Type* resultTy = inst.GetType().get();
|
|
|
|
|
|
|
|
|
|
// 指针判断:指令结果类型是指针,或者任一操作数是指针(指针算术)
|
|
|
|
|
bool isPointer = (lhsTy->IsPtrInt32() || lhsTy->IsPtrFloat() || lhsTy->IsPtrInt1() || lhsTy->IsArray()) ||
|
|
|
|
|
(rhsTy->IsPtrInt32() || rhsTy->IsPtrFloat() || rhsTy->IsPtrInt1() || rhsTy->IsArray()) ||
|
|
|
|
|
inst.GetType()->IsPtrInt32() || inst.GetType()->IsPtrFloat() || inst.GetType()->IsPtrInt1() || inst.GetType()->IsArray();
|
|
|
|
|
(rhsTy->IsPtrInt32() || rhsTy->IsPtrFloat() || rhsTy->IsPtrInt1() || rhsTy->IsArray()) ||
|
|
|
|
|
resultTy->IsPtrInt32() || resultTy->IsPtrFloat() || resultTy->IsPtrInt1() || resultTy->IsArray();
|
|
|
|
|
|
|
|
|
|
// 判断是否为纯 32 位有符号整数加法(需要提升为 64 位以避免溢出)
|
|
|
|
|
bool isI32 = !isPointer && IsInt32Type(lhsTy) && IsInt32Type(rhsTy) && IsInt32Type(resultTy);
|
|
|
|
|
|
|
|
|
|
int slotSize = isPointer ? 8 : 4;
|
|
|
|
|
PhysReg lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
|
|
|
|
|
PhysReg rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
|
|
|
|
|
PhysReg dstReg = isPointer ? PhysReg::X8 : PhysReg::W8;
|
|
|
|
|
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(slotSize); // 使用计算出的 slotSize
|
|
|
|
|
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
|
|
|
|
|
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(slotSize);
|
|
|
|
|
|
|
|
|
|
PhysReg lhsReg, rhsReg, dstReg;
|
|
|
|
|
if (isI32) {
|
|
|
|
|
// 使用 64 位寄存器,先符号扩展
|
|
|
|
|
lhsReg = PhysReg::X8;
|
|
|
|
|
rhsReg = PhysReg::X9;
|
|
|
|
|
dstReg = PhysReg::X8;
|
|
|
|
|
|
|
|
|
|
EmitValueToReg(bin.GetLhs(), PhysReg::W8, slots, block, function);
|
|
|
|
|
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::W8)});
|
|
|
|
|
|
|
|
|
|
EmitValueToReg(bin.GetRhs(), PhysReg::W9, slots, block, function);
|
|
|
|
|
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X9), Operand::Reg(PhysReg::W9)});
|
|
|
|
|
} else {
|
|
|
|
|
lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
|
|
|
|
|
rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
|
|
|
|
|
dstReg = isPointer ? PhysReg::X8 : PhysReg::W8;
|
|
|
|
|
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
|
|
|
|
|
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
block.Append(Opcode::AddRR, {Operand::Reg(dstReg), Operand::Reg(lhsReg), Operand::Reg(rhsReg)});
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
|
|
|
|
|
if (isI32) {
|
|
|
|
|
// 结果在 X8 中,只需存储低 32 位(W8)
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
} else {
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
}
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case ir::Opcode::Sub: {
|
|
|
|
|
auto& bin = static_cast<const ir::BinaryInst&>(inst);
|
|
|
|
|
const ir::Type* lhsTy = bin.GetLhs()->GetType().get();
|
|
|
|
|
const ir::Type* rhsTy = bin.GetRhs()->GetType().get();
|
|
|
|
|
|
|
|
|
|
// 指针判断:指令结果类型是指针,或者任一操作数是指针(指针算术)
|
|
|
|
|
const ir::Type* resultTy = inst.GetType().get();
|
|
|
|
|
|
|
|
|
|
bool isPointer = (lhsTy->IsPtrInt32() || lhsTy->IsPtrFloat() || lhsTy->IsPtrInt1() || lhsTy->IsArray()) ||
|
|
|
|
|
(rhsTy->IsPtrInt32() || rhsTy->IsPtrFloat() || rhsTy->IsPtrInt1() || rhsTy->IsArray()) ||
|
|
|
|
|
inst.GetType()->IsPtrInt32() || inst.GetType()->IsPtrFloat() || inst.GetType()->IsPtrInt1() || inst.GetType()->IsArray();
|
|
|
|
|
(rhsTy->IsPtrInt32() || rhsTy->IsPtrFloat() || rhsTy->IsPtrInt1() || rhsTy->IsArray()) ||
|
|
|
|
|
resultTy->IsPtrInt32() || resultTy->IsPtrFloat() || resultTy->IsPtrInt1() || resultTy->IsArray();
|
|
|
|
|
|
|
|
|
|
bool isI32 = !isPointer && IsInt32Type(lhsTy) && IsInt32Type(rhsTy) && IsInt32Type(resultTy);
|
|
|
|
|
|
|
|
|
|
int slotSize = isPointer ? 8 : 4;
|
|
|
|
|
PhysReg lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
|
|
|
|
|
PhysReg rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
|
|
|
|
|
PhysReg dstReg = isPointer ? PhysReg::X8 : PhysReg::W8;
|
|
|
|
|
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(slotSize); // 使用计算出的 slotSize
|
|
|
|
|
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
|
|
|
|
|
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(slotSize);
|
|
|
|
|
|
|
|
|
|
PhysReg lhsReg, rhsReg, dstReg;
|
|
|
|
|
if (isI32) {
|
|
|
|
|
lhsReg = PhysReg::X8;
|
|
|
|
|
rhsReg = PhysReg::X9;
|
|
|
|
|
dstReg = PhysReg::X8;
|
|
|
|
|
|
|
|
|
|
EmitValueToReg(bin.GetLhs(), PhysReg::W8, slots, block, function);
|
|
|
|
|
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::W8)});
|
|
|
|
|
|
|
|
|
|
EmitValueToReg(bin.GetRhs(), PhysReg::W9, slots, block, function);
|
|
|
|
|
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X9), Operand::Reg(PhysReg::W9)});
|
|
|
|
|
} else {
|
|
|
|
|
lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
|
|
|
|
|
rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
|
|
|
|
|
dstReg = isPointer ? PhysReg::X8 : PhysReg::W8;
|
|
|
|
|
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
|
|
|
|
|
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
block.Append(Opcode::SubRR, {Operand::Reg(dstReg), Operand::Reg(lhsReg), Operand::Reg(rhsReg)});
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
|
|
|
|
|
if (isI32) {
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
} else {
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
}
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case ir::Opcode::Mul: {
|
|
|
|
|
auto& bin = static_cast<const ir::BinaryInst&>(inst);
|
|
|
|
|
const ir::Type* ty = inst.GetType().get();
|
|
|
|
|
bool isPointer = ty->IsPtrInt32() || ty->IsPtrFloat() || ty->IsPtrInt1();
|
|
|
|
|
const ir::Type* lhsTy = bin.GetLhs()->GetType().get();
|
|
|
|
|
const ir::Type* rhsTy = bin.GetRhs()->GetType().get();
|
|
|
|
|
const ir::Type* resultTy = inst.GetType().get();
|
|
|
|
|
|
|
|
|
|
// 乘法一般不涉及指针,但保留判断
|
|
|
|
|
bool isPointer = (lhsTy->IsPtrInt32() || lhsTy->IsPtrFloat() || lhsTy->IsPtrInt1()) ||
|
|
|
|
|
(rhsTy->IsPtrInt32() || rhsTy->IsPtrFloat() || rhsTy->IsPtrInt1()) ||
|
|
|
|
|
resultTy->IsPtrInt32() || resultTy->IsPtrFloat() || resultTy->IsPtrInt1();
|
|
|
|
|
|
|
|
|
|
bool isI32 = !isPointer && IsInt32Type(lhsTy) && IsInt32Type(rhsTy) && IsInt32Type(resultTy);
|
|
|
|
|
|
|
|
|
|
int slotSize = isPointer ? 8 : 4;
|
|
|
|
|
PhysReg lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
|
|
|
|
|
PhysReg rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
|
|
|
|
|
PhysReg dstReg = isPointer ? PhysReg::X8 : PhysReg::W8; // 可复用 lhsReg
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(slotSize);
|
|
|
|
|
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 分配结果栈槽
|
|
|
|
|
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
|
|
|
|
|
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
|
|
|
|
|
block.Append(Opcode::MulRR, {Operand::Reg(dstReg),
|
|
|
|
|
Operand::Reg(lhsReg),
|
|
|
|
|
Operand::Reg(rhsReg)});
|
|
|
|
|
block.Append(Opcode::StoreStack,
|
|
|
|
|
{Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
PhysReg lhsReg, rhsReg, dstReg;
|
|
|
|
|
if (isI32) {
|
|
|
|
|
lhsReg = PhysReg::X8;
|
|
|
|
|
rhsReg = PhysReg::X9;
|
|
|
|
|
dstReg = PhysReg::X8;
|
|
|
|
|
|
|
|
|
|
EmitValueToReg(bin.GetLhs(), PhysReg::W8, slots, block, function);
|
|
|
|
|
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::W8)});
|
|
|
|
|
|
|
|
|
|
EmitValueToReg(bin.GetRhs(), PhysReg::W9, slots, block, function);
|
|
|
|
|
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X9), Operand::Reg(PhysReg::W9)});
|
|
|
|
|
} else {
|
|
|
|
|
lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
|
|
|
|
|
rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
|
|
|
|
|
dstReg = isPointer ? PhysReg::X8 : PhysReg::W8;
|
|
|
|
|
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
|
|
|
|
|
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
block.Append(Opcode::MulRR, {Operand::Reg(dstReg), Operand::Reg(lhsReg), Operand::Reg(rhsReg)});
|
|
|
|
|
|
|
|
|
|
if (isI32) {
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
} else {
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
}
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case ir::Opcode::Div: {
|
|
|
|
|
auto& bin = static_cast<const ir::BinaryInst&>(inst);
|
|
|
|
|
const ir::Type* ty = inst.GetType().get();
|
|
|
|
|
bool isPointer = ty->IsPtrInt32() || ty->IsPtrFloat() || ty->IsPtrInt1();
|
|
|
|
|
const ir::Type* lhsTy = bin.GetLhs()->GetType().get();
|
|
|
|
|
const ir::Type* rhsTy = bin.GetRhs()->GetType().get();
|
|
|
|
|
const ir::Type* resultTy = inst.GetType().get();
|
|
|
|
|
|
|
|
|
|
bool isPointer = (lhsTy->IsPtrInt32() || lhsTy->IsPtrFloat() || lhsTy->IsPtrInt1()) ||
|
|
|
|
|
(rhsTy->IsPtrInt32() || rhsTy->IsPtrFloat() || rhsTy->IsPtrInt1()) ||
|
|
|
|
|
resultTy->IsPtrInt32() || resultTy->IsPtrFloat() || resultTy->IsPtrInt1();
|
|
|
|
|
|
|
|
|
|
bool isI32 = !isPointer && IsInt32Type(lhsTy) && IsInt32Type(rhsTy) && IsInt32Type(resultTy);
|
|
|
|
|
|
|
|
|
|
int slotSize = isPointer ? 8 : 4;
|
|
|
|
|
PhysReg lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
|
|
|
|
|
PhysReg rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
|
|
|
|
|
PhysReg dstReg = isPointer ? PhysReg::X8 : PhysReg::W8; // 可复用 lhsReg
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(slotSize);
|
|
|
|
|
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 分配结果栈槽
|
|
|
|
|
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
|
|
|
|
|
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
|
|
|
|
|
block.Append(Opcode::SDivRR, {Operand::Reg(dstReg),
|
|
|
|
|
Operand::Reg(lhsReg),
|
|
|
|
|
Operand::Reg(rhsReg)});
|
|
|
|
|
block.Append(Opcode::StoreStack,
|
|
|
|
|
{Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
PhysReg lhsReg, rhsReg, dstReg;
|
|
|
|
|
if (isI32) {
|
|
|
|
|
lhsReg = PhysReg::X8;
|
|
|
|
|
rhsReg = PhysReg::X9;
|
|
|
|
|
dstReg = PhysReg::X8;
|
|
|
|
|
|
|
|
|
|
EmitValueToReg(bin.GetLhs(), PhysReg::W8, slots, block, function);
|
|
|
|
|
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::W8)});
|
|
|
|
|
|
|
|
|
|
EmitValueToReg(bin.GetRhs(), PhysReg::W9, slots, block, function);
|
|
|
|
|
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X9), Operand::Reg(PhysReg::W9)});
|
|
|
|
|
} else {
|
|
|
|
|
lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
|
|
|
|
|
rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
|
|
|
|
|
dstReg = isPointer ? PhysReg::X8 : PhysReg::W8;
|
|
|
|
|
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
|
|
|
|
|
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
block.Append(Opcode::SDivRR, {Operand::Reg(dstReg), Operand::Reg(lhsReg), Operand::Reg(rhsReg)});
|
|
|
|
|
|
|
|
|
|
if (isI32) {
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
} else {
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
}
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case ir::Opcode::Mod: {
|
|
|
|
|
// Mod 指令:a % b = a - (a / b) * b
|
|
|
|
|
// 我们直接复用提升策略:使用 64 位运算
|
|
|
|
|
const ir::Value* lhs = inst.GetOperand(0);
|
|
|
|
|
const ir::Value* rhs = inst.GetOperand(1);
|
|
|
|
|
const ir::Type* lhsTy = lhs->GetType().get();
|
|
|
|
|
const ir::Type* rhsTy = rhs->GetType().get();
|
|
|
|
|
const ir::Type* resultTy = inst.GetType().get();
|
|
|
|
|
|
|
|
|
|
bool isI32 = IsInt32Type(lhsTy) && IsInt32Type(rhsTy) && IsInt32Type(resultTy);
|
|
|
|
|
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(4); // 结果总是 32 位
|
|
|
|
|
if (isI32) {
|
|
|
|
|
// 加载并扩展 lhs
|
|
|
|
|
EmitValueToReg(lhs, PhysReg::W8, slots, block, function);
|
|
|
|
|
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::W8)});
|
|
|
|
|
// 加载并扩展 rhs
|
|
|
|
|
EmitValueToReg(rhs, PhysReg::W9, slots, block, function);
|
|
|
|
|
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X9), Operand::Reg(PhysReg::W9)});
|
|
|
|
|
|
|
|
|
|
// X10 = X8 / X9
|
|
|
|
|
block.Append(Opcode::SDivRR, {Operand::Reg(PhysReg::X10), Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::X9)});
|
|
|
|
|
// X10 = X10 * X9
|
|
|
|
|
block.Append(Opcode::MulRR, {Operand::Reg(PhysReg::X10), Operand::Reg(PhysReg::X10), Operand::Reg(PhysReg::X9)});
|
|
|
|
|
// X8 = X8 - X10
|
|
|
|
|
block.Append(Opcode::SubRR, {Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::X10)});
|
|
|
|
|
// 存储低 32 位
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
} else {
|
|
|
|
|
// 原有逻辑(假设不会用于指针或 64 位整数)
|
|
|
|
|
EmitValueToReg(lhs, PhysReg::W8, slots, block, function);
|
|
|
|
|
EmitValueToReg(rhs, PhysReg::W9, slots, block, function);
|
|
|
|
|
block.Append(Opcode::SDivRR, {Operand::Reg(PhysReg::W10), Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W9)});
|
|
|
|
|
block.Append(Opcode::MulRR, {Operand::Reg(PhysReg::W10), Operand::Reg(PhysReg::W10), Operand::Reg(PhysReg::W9)});
|
|
|
|
|
block.Append(Opcode::SubRR, {Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W10)});
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
}
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@ -900,39 +1045,6 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 处理 Mod 指令
|
|
|
|
|
case ir::Opcode::Mod: {
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
|
|
|
|
|
|
|
|
|
|
// 通过操作数获取左右值
|
|
|
|
|
const ir::Value* lhs = nullptr;
|
|
|
|
|
const ir::Value* rhs = nullptr;
|
|
|
|
|
if (inst.GetNumOperands() >= 2) {
|
|
|
|
|
lhs = inst.GetOperand(0);
|
|
|
|
|
rhs = inst.GetOperand(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lhs && rhs) {
|
|
|
|
|
EmitValueToReg(lhs, PhysReg::W8, slots, block, function);
|
|
|
|
|
EmitValueToReg(rhs, PhysReg::W9, slots, block, function);
|
|
|
|
|
|
|
|
|
|
// a % b = a - (a / b) * b
|
|
|
|
|
block.Append(Opcode::SDivRR, {Operand::Reg(PhysReg::W10),
|
|
|
|
|
Operand::Reg(PhysReg::W8),
|
|
|
|
|
Operand::Reg(PhysReg::W9)});
|
|
|
|
|
block.Append(Opcode::MulRR, {Operand::Reg(PhysReg::W10),
|
|
|
|
|
Operand::Reg(PhysReg::W10),
|
|
|
|
|
Operand::Reg(PhysReg::W9)});
|
|
|
|
|
block.Append(Opcode::SubRR, {Operand::Reg(PhysReg::W8),
|
|
|
|
|
Operand::Reg(PhysReg::W8),
|
|
|
|
|
Operand::Reg(PhysReg::W10)});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
block.Append(Opcode::StoreStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 处理 And 指令
|
|
|
|
|
case ir::Opcode::And: {
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
|
|
|
|
|
@ -1144,9 +1256,28 @@ std::unique_ptr<MachineModule> LowerToMIR(const ir::Module& module) {
|
|
|
|
|
for (const auto& global : module.GetGlobals()) {
|
|
|
|
|
int size = GetTypeSize(global->GetType().get());
|
|
|
|
|
int alignment = global->GetType()->Alignment();
|
|
|
|
|
// 简化:假设无显式初始化的全局变量都是零初始化
|
|
|
|
|
bool is_zero_init = !global->HasInitializer();
|
|
|
|
|
machine_module->AddGlobal(global->GetName(), size, alignment, is_zero_init);
|
|
|
|
|
bool has_init_data = false;
|
|
|
|
|
uint64_t init_data = 0;
|
|
|
|
|
|
|
|
|
|
if (!is_zero_init) {
|
|
|
|
|
const auto& init = global->GetInitializer();
|
|
|
|
|
// 简单处理:只支持单个元素的标量初始化(float 或 int)
|
|
|
|
|
if (init.size() == 1) {
|
|
|
|
|
if (auto* cf = dynamic_cast<const ir::ConstantFloat*>(init[0])) {
|
|
|
|
|
float fval = cf->GetValue();
|
|
|
|
|
uint32_t bits;
|
|
|
|
|
memcpy(&bits, &fval, sizeof(bits));
|
|
|
|
|
init_data = bits;
|
|
|
|
|
has_init_data = true;
|
|
|
|
|
} else if (auto* ci = dynamic_cast<const ir::ConstantInt*>(init[0])) {
|
|
|
|
|
init_data = static_cast<uint64_t>(ci->GetValue());
|
|
|
|
|
has_init_data = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
machine_module->AddGlobal(global->GetName(), size, alignment,
|
|
|
|
|
is_zero_init, has_init_data, init_data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<const ir::GlobalValue*> globals;
|
|
|
|
|
|