floats iter 4.2 fixup: 3-tuple return for builtin_binop_typed + classifier helper
This commit is contained in:
@@ -242,32 +242,45 @@ pub(crate) fn type_descriptor(t: &Type) -> String {
|
||||
/// Floats iter 4.2: arithmetic / comparison ops are type-dispatched
|
||||
/// over `{Int, Float}`. Caller (`lower_app`) resolves the arg type
|
||||
/// via `synth_arg_type` and passes it here. Returns the
|
||||
/// `(instruction, llvm_type)` pair to emit. `%` stays Int-only.
|
||||
/// `(instruction, operand_llvm_type, result_llvm_type)` triple to
|
||||
/// emit. `%` stays Int-only.
|
||||
///
|
||||
/// The triple carries operand and result types separately because
|
||||
/// comparison ops produce `i1` regardless of operand width
|
||||
/// (e.g. `icmp slt i64 ..., ... -> i1`); arithmetic produces the
|
||||
/// same type as its operands. Keeping both in the table localises
|
||||
/// the comparison-vs-arithmetic distinction here — the caller no
|
||||
/// longer has to second-guess which arm fired.
|
||||
///
|
||||
/// Comparison-op Int arms are kept here in iter 4.2 to preserve
|
||||
/// the no-regression invariant — pre-iter-4 codegen routed
|
||||
/// `<`/`<=`/`>`/`>=`/`!=` through the same Int-only `builtin_binop`
|
||||
/// table. Iter 4.3 adds the Float arms.
|
||||
pub(crate) fn builtin_binop_typed(name: &str, arg_ty: &Type) -> Option<(&'static str, &'static str)> {
|
||||
/// table. Iter 4.3 adds the Float arms (`("fcmp olt", "double", "i1")`
|
||||
/// and friends).
|
||||
pub(crate) fn builtin_binop_typed(
|
||||
name: &str,
|
||||
arg_ty: &Type,
|
||||
) -> Option<(&'static str, &'static str, &'static str)> {
|
||||
let is_int = matches!(arg_ty, Type::Con { name, .. } if name == "Int");
|
||||
let is_float = matches!(arg_ty, Type::Con { name, .. } if name == "Float");
|
||||
match (name, is_int, is_float) {
|
||||
("+", true, _) => Some(("add", "i64")),
|
||||
("+", _, true) => Some(("fadd", "double")),
|
||||
("-", true, _) => Some(("sub", "i64")),
|
||||
("-", _, true) => Some(("fsub", "double")),
|
||||
("*", true, _) => Some(("mul", "i64")),
|
||||
("*", _, true) => Some(("fmul", "double")),
|
||||
("/", true, _) => Some(("sdiv", "i64")),
|
||||
("/", _, true) => Some(("fdiv", "double")),
|
||||
("%", true, _) => Some(("srem", "i64")),
|
||||
// Int-arm comparisons preserved from pre-iter-4 `builtin_binop`.
|
||||
("+", true, _) => Some(("add", "i64", "i64")),
|
||||
("+", _, true) => Some(("fadd", "double", "double")),
|
||||
("-", true, _) => Some(("sub", "i64", "i64")),
|
||||
("-", _, true) => Some(("fsub", "double", "double")),
|
||||
("*", true, _) => Some(("mul", "i64", "i64")),
|
||||
("*", _, true) => Some(("fmul", "double", "double")),
|
||||
("/", true, _) => Some(("sdiv", "i64", "i64")),
|
||||
("/", _, true) => Some(("fdiv", "double", "double")),
|
||||
("%", true, _) => Some(("srem", "i64", "i64")),
|
||||
// Comparison ops: operand types differ, result is always `i1`.
|
||||
// Int-arm comparisons preserved from pre-iter-4 `builtin_binop`;
|
||||
// Float arms land in iter 4.3.
|
||||
("!=", true, _) => Some(("icmp ne", "i64")),
|
||||
("<", true, _) => Some(("icmp slt", "i64")),
|
||||
("<=", true, _) => Some(("icmp sle", "i64")),
|
||||
(">", true, _) => Some(("icmp sgt", "i64")),
|
||||
(">=", true, _) => Some(("icmp sge", "i64")),
|
||||
("!=", true, _) => Some(("icmp ne", "i64", "i1")),
|
||||
("<", true, _) => Some(("icmp slt", "i64", "i1")),
|
||||
("<=", true, _) => Some(("icmp sle", "i64", "i1")),
|
||||
(">", true, _) => Some(("icmp sgt", "i64", "i1")),
|
||||
(">=", true, _) => Some(("icmp sge", "i64", "i1")),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user