mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
assembly for irem and urem
This commit is contained in:
parent
74444d2883
commit
43624ade27
4 changed files with 138 additions and 15 deletions
|
@ -581,6 +581,32 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
|
||||||
udiv_reg64_reg64_reg64(buf, dst, src1, src2);
|
udiv_reg64_reg64_reg64(buf, dst, src1, src2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn irem_reg64_reg64_reg64<'a, ASM, CC>(
|
||||||
|
_buf: &mut Vec<'a, u8>,
|
||||||
|
_storage_manager: &mut StorageManager<'a, '_, AArch64GeneralReg, AArch64FloatReg, ASM, CC>,
|
||||||
|
_dst: AArch64GeneralReg,
|
||||||
|
_src1: AArch64GeneralReg,
|
||||||
|
_src2: AArch64GeneralReg,
|
||||||
|
) where
|
||||||
|
ASM: Assembler<AArch64GeneralReg, AArch64FloatReg>,
|
||||||
|
CC: CallConv<AArch64GeneralReg, AArch64FloatReg, ASM>,
|
||||||
|
{
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn urem_reg64_reg64_reg64<'a, ASM, CC>(
|
||||||
|
_buf: &mut Vec<'a, u8>,
|
||||||
|
_storage_manager: &mut StorageManager<'a, '_, AArch64GeneralReg, AArch64FloatReg, ASM, CC>,
|
||||||
|
_dst: AArch64GeneralReg,
|
||||||
|
_src1: AArch64GeneralReg,
|
||||||
|
_src2: AArch64GeneralReg,
|
||||||
|
) where
|
||||||
|
ASM: Assembler<AArch64GeneralReg, AArch64FloatReg>,
|
||||||
|
CC: CallConv<AArch64GeneralReg, AArch64FloatReg, ASM>,
|
||||||
|
{
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_freg32_freg32_freg32(
|
fn mul_freg32_freg32_freg32(
|
||||||
buf: &mut Vec<'_, u8>,
|
buf: &mut Vec<'_, u8>,
|
||||||
|
|
|
@ -387,6 +387,7 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait>: Sized + Copy {
|
||||||
) where
|
) where
|
||||||
ASM: Assembler<GeneralReg, FloatReg>,
|
ASM: Assembler<GeneralReg, FloatReg>,
|
||||||
CC: CallConv<GeneralReg, FloatReg, ASM>;
|
CC: CallConv<GeneralReg, FloatReg, ASM>;
|
||||||
|
|
||||||
fn udiv_reg64_reg64_reg64<'a, ASM, CC>(
|
fn udiv_reg64_reg64_reg64<'a, ASM, CC>(
|
||||||
buf: &mut Vec<'a, u8>,
|
buf: &mut Vec<'a, u8>,
|
||||||
storage_manager: &mut StorageManager<'a, '_, GeneralReg, FloatReg, ASM, CC>,
|
storage_manager: &mut StorageManager<'a, '_, GeneralReg, FloatReg, ASM, CC>,
|
||||||
|
@ -397,6 +398,26 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait>: Sized + Copy {
|
||||||
ASM: Assembler<GeneralReg, FloatReg>,
|
ASM: Assembler<GeneralReg, FloatReg>,
|
||||||
CC: CallConv<GeneralReg, FloatReg, ASM>;
|
CC: CallConv<GeneralReg, FloatReg, ASM>;
|
||||||
|
|
||||||
|
fn irem_reg64_reg64_reg64<'a, ASM, CC>(
|
||||||
|
buf: &mut Vec<'a, u8>,
|
||||||
|
storage_manager: &mut StorageManager<'a, '_, GeneralReg, FloatReg, ASM, CC>,
|
||||||
|
dst: GeneralReg,
|
||||||
|
src1: GeneralReg,
|
||||||
|
src2: GeneralReg,
|
||||||
|
) where
|
||||||
|
ASM: Assembler<GeneralReg, FloatReg>,
|
||||||
|
CC: CallConv<GeneralReg, FloatReg, ASM>;
|
||||||
|
|
||||||
|
fn urem_reg64_reg64_reg64<'a, ASM, CC>(
|
||||||
|
buf: &mut Vec<'a, u8>,
|
||||||
|
storage_manager: &mut StorageManager<'a, '_, GeneralReg, FloatReg, ASM, CC>,
|
||||||
|
dst: GeneralReg,
|
||||||
|
src1: GeneralReg,
|
||||||
|
src2: GeneralReg,
|
||||||
|
) where
|
||||||
|
ASM: Assembler<GeneralReg, FloatReg>,
|
||||||
|
CC: CallConv<GeneralReg, FloatReg, ASM>;
|
||||||
|
|
||||||
fn sub_reg64_reg64_imm32(buf: &mut Vec<'_, u8>, dst: GeneralReg, src1: GeneralReg, imm32: i32);
|
fn sub_reg64_reg64_imm32(buf: &mut Vec<'_, u8>, dst: GeneralReg, src1: GeneralReg, imm32: i32);
|
||||||
fn sub_reg64_reg64_reg64(
|
fn sub_reg64_reg64_reg64(
|
||||||
buf: &mut Vec<'_, u8>,
|
buf: &mut Vec<'_, u8>,
|
||||||
|
@ -1180,6 +1201,50 @@ impl<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_num_rem(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, layout: &InLayout<'a>) {
|
||||||
|
match self.layout_interner.get(*layout) {
|
||||||
|
Layout::Builtin(Builtin::Int(
|
||||||
|
IntWidth::I64 | IntWidth::I32 | IntWidth::I16 | IntWidth::I8,
|
||||||
|
)) => {
|
||||||
|
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
||||||
|
let src1_reg = self
|
||||||
|
.storage_manager
|
||||||
|
.load_to_general_reg(&mut self.buf, src1);
|
||||||
|
let src2_reg = self
|
||||||
|
.storage_manager
|
||||||
|
.load_to_general_reg(&mut self.buf, src2);
|
||||||
|
|
||||||
|
ASM::irem_reg64_reg64_reg64(
|
||||||
|
&mut self.buf,
|
||||||
|
&mut self.storage_manager,
|
||||||
|
dst_reg,
|
||||||
|
src1_reg,
|
||||||
|
src2_reg,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Layout::Builtin(Builtin::Int(
|
||||||
|
IntWidth::U64 | IntWidth::U32 | IntWidth::U16 | IntWidth::U8,
|
||||||
|
)) => {
|
||||||
|
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
||||||
|
let src1_reg = self
|
||||||
|
.storage_manager
|
||||||
|
.load_to_general_reg(&mut self.buf, src1);
|
||||||
|
let src2_reg = self
|
||||||
|
.storage_manager
|
||||||
|
.load_to_general_reg(&mut self.buf, src2);
|
||||||
|
|
||||||
|
ASM::urem_reg64_reg64_reg64(
|
||||||
|
&mut self.buf,
|
||||||
|
&mut self.storage_manager,
|
||||||
|
dst_reg,
|
||||||
|
src1_reg,
|
||||||
|
src2_reg,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
x => todo!("NumDiv: layout, {:?}", x),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn build_num_neg(&mut self, dst: &Symbol, src: &Symbol, layout: &InLayout<'a>) {
|
fn build_num_neg(&mut self, dst: &Symbol, src: &Symbol, layout: &InLayout<'a>) {
|
||||||
match self.layout_interner.get(*layout) {
|
match self.layout_interner.get(*layout) {
|
||||||
Layout::Builtin(Builtin::Int(IntWidth::I64 | IntWidth::U64)) => {
|
Layout::Builtin(Builtin::Int(IntWidth::I64 | IntWidth::U64)) => {
|
||||||
|
|
|
@ -1322,6 +1322,46 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
|
||||||
mov_reg64_reg64(buf, dst, X86_64GeneralReg::RAX);
|
mov_reg64_reg64(buf, dst, X86_64GeneralReg::RAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn irem_reg64_reg64_reg64<'a, ASM, CC>(
|
||||||
|
buf: &mut Vec<'a, u8>,
|
||||||
|
storage_manager: &mut StorageManager<'a, '_, X86_64GeneralReg, X86_64FloatReg, ASM, CC>,
|
||||||
|
dst: X86_64GeneralReg,
|
||||||
|
src1: X86_64GeneralReg,
|
||||||
|
src2: X86_64GeneralReg,
|
||||||
|
) where
|
||||||
|
ASM: Assembler<X86_64GeneralReg, X86_64FloatReg>,
|
||||||
|
CC: CallConv<X86_64GeneralReg, X86_64FloatReg, ASM>,
|
||||||
|
{
|
||||||
|
use crate::generic64::RegStorage;
|
||||||
|
|
||||||
|
storage_manager.ensure_reg_free(buf, RegStorage::General(X86_64GeneralReg::RAX));
|
||||||
|
storage_manager.ensure_reg_free(buf, RegStorage::General(X86_64GeneralReg::RDX));
|
||||||
|
|
||||||
|
mov_reg64_reg64(buf, X86_64GeneralReg::RAX, src1);
|
||||||
|
idiv_reg64_reg64(buf, src2);
|
||||||
|
mov_reg64_reg64(buf, dst, X86_64GeneralReg::RDX);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn urem_reg64_reg64_reg64<'a, ASM, CC>(
|
||||||
|
buf: &mut Vec<'a, u8>,
|
||||||
|
storage_manager: &mut StorageManager<'a, '_, X86_64GeneralReg, X86_64FloatReg, ASM, CC>,
|
||||||
|
dst: X86_64GeneralReg,
|
||||||
|
src1: X86_64GeneralReg,
|
||||||
|
src2: X86_64GeneralReg,
|
||||||
|
) where
|
||||||
|
ASM: Assembler<X86_64GeneralReg, X86_64FloatReg>,
|
||||||
|
CC: CallConv<X86_64GeneralReg, X86_64FloatReg, ASM>,
|
||||||
|
{
|
||||||
|
use crate::generic64::RegStorage;
|
||||||
|
|
||||||
|
storage_manager.ensure_reg_free(buf, RegStorage::General(X86_64GeneralReg::RAX));
|
||||||
|
storage_manager.ensure_reg_free(buf, RegStorage::General(X86_64GeneralReg::RDX));
|
||||||
|
|
||||||
|
mov_reg64_reg64(buf, X86_64GeneralReg::RAX, src1);
|
||||||
|
udiv_reg64_reg64(buf, src2);
|
||||||
|
mov_reg64_reg64(buf, dst, X86_64GeneralReg::RDX);
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn jmp_imm32(buf: &mut Vec<'_, u8>, offset: i32) -> usize {
|
fn jmp_imm32(buf: &mut Vec<'_, u8>, offset: i32) -> usize {
|
||||||
jmp_imm32(buf, offset);
|
jmp_imm32(buf, offset);
|
||||||
|
|
|
@ -1176,29 +1176,21 @@ fn gen_div_checked_by_zero_i64() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
|
||||||
fn gen_rem_i64() {
|
fn gen_rem_i64() {
|
||||||
assert_evals_to!(
|
assert_evals_to!("Num.rem 8 3", 2, i64);
|
||||||
indoc!(
|
|
||||||
r#"
|
|
||||||
Num.rem 8 3
|
|
||||||
"#
|
|
||||||
),
|
|
||||||
2,
|
|
||||||
i64
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
|
||||||
fn gen_rem_checked_div_by_zero_i64() {
|
fn gen_rem_checked_div_by_zero_i64() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when Num.remChecked 8 0 is
|
when Num.remChecked 8 0 is
|
||||||
Err DivByZero -> 4
|
Err DivByZero -> 4
|
||||||
Ok _ -> -23
|
Ok _ -> -23
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
4,
|
4,
|
||||||
i64
|
i64
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue