Skip to content

Commit

Permalink
rt: Emit Int128 constants in epilog on x64
Browse files Browse the repository at this point in the history
  • Loading branch information
dinfuehr committed Jan 5, 2025
1 parent 17eea00 commit 3eab48b
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 26 deletions.
4 changes: 4 additions & 0 deletions dora-asm/src/arm64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,10 @@ impl AssemblerArm64 {
pub fn emit_u64(&mut self, value: u64) {
self.buffer.emit_u64(value);
}

pub fn emit_u128(&mut self, value: u128) {
self.buffer.emit_u128(value);
}
}

impl AssemblerArm64 {
Expand Down
11 changes: 11 additions & 0 deletions dora-asm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,15 @@ impl AssemblerBuffer {
}
self.position += 8;
}

fn emit_u128(&mut self, value: u128) {
if self.position == self.code.len() {
self.code.write_u128::<LittleEndian>(value).unwrap()
} else {
(&mut self.code[self.position..])
.write_u128::<LittleEndian>(value)
.unwrap();
}
self.position += 16;
}
}
46 changes: 46 additions & 0 deletions dora-asm/src/x64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ impl AssemblerX64 {
pub fn emit_u64(&mut self, value: u64) {
self.buffer.emit_u64(value);
}

pub fn emit_u128(&mut self, value: u128) {
self.buffer.emit_u128(value);
}
}

impl AssemblerX64 {
Expand Down Expand Up @@ -218,6 +222,16 @@ impl AssemblerX64 {
self.emit_address(dest.low_bits(), src);
}

pub fn andps_rl(&mut self, dest: XmmRegister, src: Label) {
debug_assert!(!self.has_avx2);
if dest.needs_rex() {
self.emit_rex(false, true, false, false);
}
self.emit_u8(0x0f);
self.emit_u8(0x54);
self.emit_label_address(dest.low_bits(), src);
}

pub fn andq_ri(&mut self, dest: Register, imm: Immediate) {
self.emit_alu64_imm(dest, imm, 0b100, 0x25);
}
Expand Down Expand Up @@ -1380,6 +1394,22 @@ impl AssemblerX64 {
self.emit_address(dest.low_bits(), rhs);
}

pub fn vandpd_rl(&mut self, dest: XmmRegister, lhs: XmmRegister, rhs: Label) {
debug_assert!(self.has_avx2);
self.emit_vex(
dest.needs_rex(),
false,
false,
VEX_MMMMM_0F,
VEX_W0,
lhs.value(),
VEX_L_SCALAR_128,
VEX_PP_66,
);
self.emit_u8(0x54);
self.emit_label_address(dest.low_bits(), rhs);
}

pub fn vandps_ra(&mut self, dest: XmmRegister, lhs: XmmRegister, rhs: Address) {
debug_assert!(self.has_avx2);
self.emit_vex(
Expand All @@ -1396,6 +1426,22 @@ impl AssemblerX64 {
self.emit_address(dest.low_bits(), rhs);
}

pub fn vandps_rl(&mut self, dest: XmmRegister, lhs: XmmRegister, label: Label) {
debug_assert!(self.has_avx2);
self.emit_vex(
dest.needs_rex(),
false,
false,
VEX_MMMMM_0F,
VEX_W0,
lhs.value(),
VEX_L_SCALAR_128,
VEX_PP_NONE,
);
self.emit_u8(0x54);
self.emit_label_address(dest.low_bits(), label);
}

pub fn vcvtsd2ss_rr(&mut self, dest: XmmRegister, lhs: XmmRegister, rhs: XmmRegister) {
debug_assert!(self.has_avx2);
self.emit_vex(
Expand Down
5 changes: 5 additions & 0 deletions dora-runtime/src/masm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ impl NewConstPool {
pub enum EpilogConstant {
Float32(f32),
Float64(f64),
Int128(u128),
Address(Address),
JumpTable(Vec<Label>),
}
Expand Down Expand Up @@ -205,6 +206,10 @@ impl MacroAssembler {
self.asm.emit_u64(unsafe { std::mem::transmute(*value) });
}

EpilogConstant::Int128(value) => {
self.asm.emit_u128(*value);
}

EpilogConstant::JumpTable(targets) => {
for target in targets {
let offset = self.asm.position();
Expand Down
33 changes: 7 additions & 26 deletions dora-runtime/src/masm/x64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1478,42 +1478,23 @@ impl MacroAssembler {
(1 << 63) - 1
};

let const_offset = self.add_const_i128(value);
let inst_start = self.pos() as i32;
let label = self.create_label();
self.epilog_constants
.push((label, EpilogConstant::Int128(value)));

if has_avx2() {
match mode {
MachineMode::Float32 => {
self.asm
.vandps_ra(dest.into(), src.into(), AsmAddress::rip(0))
}
MachineMode::Float64 => {
self.asm
.vandpd_ra(dest.into(), src.into(), AsmAddress::rip(0))
}
MachineMode::Float32 => self.asm.vandps_rl(dest.into(), src.into(), label),
MachineMode::Float64 => self.asm.vandpd_rl(dest.into(), src.into(), label),
_ => unimplemented!(),
}

let inst_end = self.pos() as i32;
let disp = -(const_offset + inst_end);
self.asm.set_position(self.pos() - 4);
self.asm.emit_u32(disp as u32);
self.asm.set_position_end();
} else {
let xmm_reg: XmmRegister = src.into();

let inst_size = 7 + if xmm_reg.needs_rex() { 1 } else { 0 };

let address = AsmAddress::rip(-(const_offset + inst_start + inst_size));

match mode {
MachineMode::Float32 => self.asm.andps_ra(src.into(), address),
MachineMode::Float64 => self.asm.andps_ra(src.into(), address),
MachineMode::Float32 => self.asm.andps_rl(src.into(), label),
MachineMode::Float64 => self.asm.andps_rl(src.into(), label),
_ => unimplemented!(),
}

assert_eq!(inst_size, self.pos() as i32 - inst_start);

if dest != src {
self.copy_freg(mode, dest, src);
}
Expand Down

0 comments on commit 3eab48b

Please sign in to comment.