76 lines
2.4 KiB
Python
76 lines
2.4 KiB
Python
|
|
"""
|
||
|
|
BinOp (Binary Operation) instruction lowering
|
||
|
|
Handles +, -, *, /, %, &, |, ^, <<, >>
|
||
|
|
"""
|
||
|
|
|
||
|
|
import llvmlite.ir as ir
|
||
|
|
from typing import Dict
|
||
|
|
|
||
|
|
def lower_binop(
|
||
|
|
builder: ir.IRBuilder,
|
||
|
|
resolver, # Resolver instance
|
||
|
|
op: str,
|
||
|
|
lhs: int,
|
||
|
|
rhs: int,
|
||
|
|
dst: int,
|
||
|
|
vmap: Dict[int, ir.Value],
|
||
|
|
current_block: ir.Block
|
||
|
|
) -> None:
|
||
|
|
"""
|
||
|
|
Lower MIR BinOp instruction
|
||
|
|
|
||
|
|
Args:
|
||
|
|
builder: Current LLVM IR builder
|
||
|
|
resolver: Resolver for value resolution
|
||
|
|
op: Operation string (+, -, *, /, etc.)
|
||
|
|
lhs: Left operand value ID
|
||
|
|
rhs: Right operand value ID
|
||
|
|
dst: Destination value ID
|
||
|
|
vmap: Value map
|
||
|
|
current_block: Current basic block
|
||
|
|
"""
|
||
|
|
# Resolve operands as i64 (using resolver when available)
|
||
|
|
# For now, simple vmap lookup
|
||
|
|
lhs_val = vmap.get(lhs, ir.Constant(ir.IntType(64), 0))
|
||
|
|
rhs_val = vmap.get(rhs, ir.Constant(ir.IntType(64), 0))
|
||
|
|
|
||
|
|
# Ensure both are i64
|
||
|
|
i64 = ir.IntType(64)
|
||
|
|
if hasattr(lhs_val, 'type') and lhs_val.type != i64:
|
||
|
|
# Type conversion if needed
|
||
|
|
if lhs_val.type.is_pointer:
|
||
|
|
lhs_val = builder.ptrtoint(lhs_val, i64)
|
||
|
|
if hasattr(rhs_val, 'type') and rhs_val.type != i64:
|
||
|
|
if rhs_val.type.is_pointer:
|
||
|
|
rhs_val = builder.ptrtoint(rhs_val, i64)
|
||
|
|
|
||
|
|
# Perform operation
|
||
|
|
if op == '+':
|
||
|
|
result = builder.add(lhs_val, rhs_val, name=f"add_{dst}")
|
||
|
|
elif op == '-':
|
||
|
|
result = builder.sub(lhs_val, rhs_val, name=f"sub_{dst}")
|
||
|
|
elif op == '*':
|
||
|
|
result = builder.mul(lhs_val, rhs_val, name=f"mul_{dst}")
|
||
|
|
elif op == '/':
|
||
|
|
# Signed division
|
||
|
|
result = builder.sdiv(lhs_val, rhs_val, name=f"div_{dst}")
|
||
|
|
elif op == '%':
|
||
|
|
# Signed remainder
|
||
|
|
result = builder.srem(lhs_val, rhs_val, name=f"rem_{dst}")
|
||
|
|
elif op == '&':
|
||
|
|
result = builder.and_(lhs_val, rhs_val, name=f"and_{dst}")
|
||
|
|
elif op == '|':
|
||
|
|
result = builder.or_(lhs_val, rhs_val, name=f"or_{dst}")
|
||
|
|
elif op == '^':
|
||
|
|
result = builder.xor(lhs_val, rhs_val, name=f"xor_{dst}")
|
||
|
|
elif op == '<<':
|
||
|
|
result = builder.shl(lhs_val, rhs_val, name=f"shl_{dst}")
|
||
|
|
elif op == '>>':
|
||
|
|
# Arithmetic shift right
|
||
|
|
result = builder.ashr(lhs_val, rhs_val, name=f"ashr_{dst}")
|
||
|
|
else:
|
||
|
|
# Unknown op - return zero
|
||
|
|
result = ir.Constant(i64, 0)
|
||
|
|
|
||
|
|
# Store result
|
||
|
|
vmap[dst] = result
|