add decimal comparisons and conversions to wasm backend

This commit is contained in:
Folkert 2023-09-13 22:28:39 +02:00
parent d7bc03c589
commit 5bcfd91f3a
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
4 changed files with 134 additions and 7 deletions

View file

@ -1099,7 +1099,23 @@ impl<'a> LowLevelCall<'a> {
}
F32 => backend.code_builder.f32_gt(),
F64 => backend.code_builder.f64_gt(),
x => todo!("{:?} for {:?}", self.lowlevel, x),
I128 => {
self.load_args(backend);
let intrinsic = if symbol_is_signed_int(backend, self.arguments[0]) {
&bitcode::NUM_GREATER_THAN[IntWidth::I128]
} else {
&bitcode::NUM_GREATER_THAN[IntWidth::U128]
};
self.load_args_and_call_zig(backend, intrinsic);
}
Decimal => {
// same as i128
self.load_args_and_call_zig(
backend,
&bitcode::NUM_GREATER_THAN[IntWidth::I128],
);
}
}
}
NumGte => {
@ -1121,7 +1137,23 @@ impl<'a> LowLevelCall<'a> {
}
F32 => backend.code_builder.f32_ge(),
F64 => backend.code_builder.f64_ge(),
x => todo!("{:?} for {:?}", self.lowlevel, x),
I128 => {
self.load_args(backend);
let intrinsic = if symbol_is_signed_int(backend, self.arguments[0]) {
&bitcode::NUM_GREATER_THAN_OR_EQUAL[IntWidth::I128]
} else {
&bitcode::NUM_GREATER_THAN_OR_EQUAL[IntWidth::U128]
};
self.load_args_and_call_zig(backend, intrinsic);
}
Decimal => {
// same as i128
self.load_args_and_call_zig(
backend,
&bitcode::NUM_GREATER_THAN_OR_EQUAL[IntWidth::I128],
);
}
}
}
NumLt => {
@ -1143,7 +1175,23 @@ impl<'a> LowLevelCall<'a> {
}
F32 => backend.code_builder.f32_lt(),
F64 => backend.code_builder.f64_lt(),
x => todo!("{:?} for {:?}", self.lowlevel, x),
I128 => {
self.load_args(backend);
let intrinsic = if symbol_is_signed_int(backend, self.arguments[0]) {
&bitcode::NUM_LESS_THAN[IntWidth::I128]
} else {
&bitcode::NUM_LESS_THAN[IntWidth::U128]
};
self.load_args_and_call_zig(backend, intrinsic);
}
Decimal => {
// same as i128
self.load_args_and_call_zig(
backend,
&bitcode::NUM_LESS_THAN[IntWidth::I128],
);
}
}
}
NumLte => {
@ -1166,7 +1214,23 @@ impl<'a> LowLevelCall<'a> {
}
F32 => backend.code_builder.f32_le(),
F64 => backend.code_builder.f64_le(),
x => todo!("{:?} for {:?}", self.lowlevel, x),
I128 => {
self.load_args(backend);
let intrinsic = if symbol_is_signed_int(backend, self.arguments[0]) {
&bitcode::NUM_LESS_THAN_OR_EQUAL[IntWidth::I128]
} else {
&bitcode::NUM_LESS_THAN_OR_EQUAL[IntWidth::U128]
};
self.load_args_and_call_zig(backend, intrinsic);
}
Decimal => {
// same as i128
self.load_args_and_call_zig(
backend,
&bitcode::NUM_LESS_THAN_OR_EQUAL[IntWidth::I128],
);
}
}
}
NumCompare => {
@ -1216,7 +1280,10 @@ impl<'a> LowLevelCall<'a> {
backend.code_builder.f64_lt();
backend.code_builder.i32_add();
}
x => todo!("{:?} for {:?}", self.lowlevel, x),
I128 | Decimal => {
self.load_args(backend);
self.load_args_and_call_zig(backend, &bitcode::NUM_COMPARE[IntWidth::I128]);
}
}
}
NumDivFrac => {
@ -1494,6 +1561,7 @@ impl<'a> LowLevelCall<'a> {
self.load_args(backend);
let ret_type = CodeGenNumType::from(self.ret_layout);
let arg_type = CodeGenNumType::for_symbol(backend, self.arguments[0]);
let arg_is_signed = symbol_is_signed_int(backend, self.arguments[0]);
match (ret_type, arg_type) {
(F32, I32) => backend.code_builder.f32_convert_s_i32(),
(F32, I64) => backend.code_builder.f32_convert_s_i64(),
@ -1505,6 +1573,36 @@ impl<'a> LowLevelCall<'a> {
(F64, F32) => backend.code_builder.f64_promote_f32(),
(F64, F64) => {}
(Decimal, I32) => {
let int_width = match arg_is_signed {
true => IntWidth::I32,
false => IntWidth::U32,
};
self.load_args_and_call_zig(backend, &bitcode::DEC_FROM_INT[int_width]);
}
(Decimal, I64) => {
let int_width = match arg_is_signed {
true => IntWidth::I64,
false => IntWidth::U64,
};
self.load_args_and_call_zig(backend, &bitcode::DEC_FROM_INT[int_width]);
}
(Decimal, F32) => {
self.load_args_and_call_zig(
backend,
&bitcode::DEC_FROM_FLOAT[FloatWidth::F32],
);
}
(Decimal, F64) => {
self.load_args_and_call_zig(
backend,
&bitcode::DEC_FROM_FLOAT[FloatWidth::F64],
);
}
(Decimal, Decimal) => {}
_ => todo!("{:?}: {:?} -> {:?}", self.lowlevel, arg_type, ret_type),
}
}