mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-23 05:31:32 +00:00
Add i32 rmw add and sub.
This commit is contained in:
@ -5489,6 +5489,188 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
|
|||||||
ret);
|
ret);
|
||||||
self.machine.release_temp_gpr(value);
|
self.machine.release_temp_gpr(value);
|
||||||
}
|
}
|
||||||
|
Operator::I32AtomicRmw8UAdd { ref memarg } => {
|
||||||
|
let loc = get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
|
let target =
|
||||||
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
|
let ret = self.machine.acquire_locations(
|
||||||
|
a,
|
||||||
|
&[(WpType::I32, MachineValue::WasmStack(self.value_stack.len()))],
|
||||||
|
false,
|
||||||
|
)[0];
|
||||||
|
self.value_stack.push(ret);
|
||||||
|
|
||||||
|
let value = self.machine.acquire_temp_gpr().unwrap();
|
||||||
|
a.emit_movzx(
|
||||||
|
Size::S8,
|
||||||
|
loc,
|
||||||
|
Size::S32,
|
||||||
|
Location::GPR(value));
|
||||||
|
Self::emit_memory_op(
|
||||||
|
module_info,
|
||||||
|
&self.config,
|
||||||
|
a,
|
||||||
|
&mut self.machine,
|
||||||
|
target,
|
||||||
|
memarg,
|
||||||
|
true,
|
||||||
|
4,
|
||||||
|
|a, _m, addr| {
|
||||||
|
a.emit_lock_xadd(Size::S8, Location::GPR(value), Location::Memory(addr, 0))
|
||||||
|
}
|
||||||
|
);
|
||||||
|
a.emit_mov(
|
||||||
|
Size::S32,
|
||||||
|
Location::GPR(value),
|
||||||
|
ret);
|
||||||
|
self.machine.release_temp_gpr(value);
|
||||||
|
}
|
||||||
|
Operator::I32AtomicRmw16UAdd { ref memarg } => {
|
||||||
|
let loc = get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
|
let target =
|
||||||
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
|
let ret = self.machine.acquire_locations(
|
||||||
|
a,
|
||||||
|
&[(WpType::I32, MachineValue::WasmStack(self.value_stack.len()))],
|
||||||
|
false,
|
||||||
|
)[0];
|
||||||
|
self.value_stack.push(ret);
|
||||||
|
|
||||||
|
let value = self.machine.acquire_temp_gpr().unwrap();
|
||||||
|
a.emit_movzx(
|
||||||
|
Size::S16,
|
||||||
|
loc,
|
||||||
|
Size::S32,
|
||||||
|
Location::GPR(value));
|
||||||
|
Self::emit_memory_op(
|
||||||
|
module_info,
|
||||||
|
&self.config,
|
||||||
|
a,
|
||||||
|
&mut self.machine,
|
||||||
|
target,
|
||||||
|
memarg,
|
||||||
|
true,
|
||||||
|
4,
|
||||||
|
|a, _m, addr| {
|
||||||
|
a.emit_lock_xadd(Size::S16, Location::GPR(value), Location::Memory(addr, 0))
|
||||||
|
}
|
||||||
|
);
|
||||||
|
a.emit_mov(
|
||||||
|
Size::S32,
|
||||||
|
Location::GPR(value),
|
||||||
|
ret);
|
||||||
|
self.machine.release_temp_gpr(value);
|
||||||
|
}
|
||||||
|
Operator::I32AtomicRmwSub { ref memarg } => {
|
||||||
|
let loc = get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
|
let target =
|
||||||
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
|
let ret = self.machine.acquire_locations(
|
||||||
|
a,
|
||||||
|
&[(WpType::I32, MachineValue::WasmStack(self.value_stack.len()))],
|
||||||
|
false,
|
||||||
|
)[0];
|
||||||
|
self.value_stack.push(ret);
|
||||||
|
|
||||||
|
let value = self.machine.acquire_temp_gpr().unwrap();
|
||||||
|
a.emit_mov(
|
||||||
|
Size::S32,
|
||||||
|
loc,
|
||||||
|
Location::GPR(value));
|
||||||
|
a.emit_neg(Size::S32, Location::GPR(value));
|
||||||
|
Self::emit_memory_op(
|
||||||
|
module_info,
|
||||||
|
&self.config,
|
||||||
|
a,
|
||||||
|
&mut self.machine,
|
||||||
|
target,
|
||||||
|
memarg,
|
||||||
|
true,
|
||||||
|
4,
|
||||||
|
|a, _m, addr| {
|
||||||
|
a.emit_lock_xadd(Size::S32, Location::GPR(value), Location::Memory(addr, 0))
|
||||||
|
}
|
||||||
|
);
|
||||||
|
a.emit_mov(
|
||||||
|
Size::S32,
|
||||||
|
Location::GPR(value),
|
||||||
|
ret);
|
||||||
|
self.machine.release_temp_gpr(value);
|
||||||
|
}
|
||||||
|
Operator::I32AtomicRmw8USub { ref memarg } => {
|
||||||
|
let loc = get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
|
let target =
|
||||||
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
|
let ret = self.machine.acquire_locations(
|
||||||
|
a,
|
||||||
|
&[(WpType::I32, MachineValue::WasmStack(self.value_stack.len()))],
|
||||||
|
false,
|
||||||
|
)[0];
|
||||||
|
self.value_stack.push(ret);
|
||||||
|
|
||||||
|
let value = self.machine.acquire_temp_gpr().unwrap();
|
||||||
|
a.emit_movzx(
|
||||||
|
Size::S8,
|
||||||
|
loc,
|
||||||
|
Size::S32,
|
||||||
|
Location::GPR(value));
|
||||||
|
a.emit_neg(Size::S8, Location::GPR(value));
|
||||||
|
Self::emit_memory_op(
|
||||||
|
module_info,
|
||||||
|
&self.config,
|
||||||
|
a,
|
||||||
|
&mut self.machine,
|
||||||
|
target,
|
||||||
|
memarg,
|
||||||
|
true,
|
||||||
|
4,
|
||||||
|
|a, _m, addr| {
|
||||||
|
a.emit_lock_xadd(Size::S8, Location::GPR(value), Location::Memory(addr, 0))
|
||||||
|
}
|
||||||
|
);
|
||||||
|
a.emit_mov(
|
||||||
|
Size::S32,
|
||||||
|
Location::GPR(value),
|
||||||
|
ret);
|
||||||
|
self.machine.release_temp_gpr(value);
|
||||||
|
}
|
||||||
|
Operator::I32AtomicRmw16USub { ref memarg } => {
|
||||||
|
let loc = get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
|
let target =
|
||||||
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
|
let ret = self.machine.acquire_locations(
|
||||||
|
a,
|
||||||
|
&[(WpType::I32, MachineValue::WasmStack(self.value_stack.len()))],
|
||||||
|
false,
|
||||||
|
)[0];
|
||||||
|
self.value_stack.push(ret);
|
||||||
|
|
||||||
|
let value = self.machine.acquire_temp_gpr().unwrap();
|
||||||
|
a.emit_movzx(
|
||||||
|
Size::S16,
|
||||||
|
loc,
|
||||||
|
Size::S32,
|
||||||
|
Location::GPR(value));
|
||||||
|
a.emit_neg(Size::S16, Location::GPR(value));
|
||||||
|
Self::emit_memory_op(
|
||||||
|
module_info,
|
||||||
|
&self.config,
|
||||||
|
a,
|
||||||
|
&mut self.machine,
|
||||||
|
target,
|
||||||
|
memarg,
|
||||||
|
true,
|
||||||
|
4,
|
||||||
|
|a, _m, addr| {
|
||||||
|
a.emit_lock_xadd(Size::S16, Location::GPR(value), Location::Memory(addr, 0))
|
||||||
|
}
|
||||||
|
);
|
||||||
|
a.emit_mov(
|
||||||
|
Size::S32,
|
||||||
|
Location::GPR(value),
|
||||||
|
ret);
|
||||||
|
self.machine.release_temp_gpr(value);
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(CodegenError {
|
return Err(CodegenError {
|
||||||
message: format!("not yet implemented: {:?}", op),
|
message: format!("not yet implemented: {:?}", op),
|
||||||
|
@ -78,6 +78,7 @@ pub trait Emitter {
|
|||||||
fn emit_cmp(&mut self, sz: Size, left: Location, right: Location);
|
fn emit_cmp(&mut self, sz: Size, left: Location, right: Location);
|
||||||
fn emit_add(&mut self, sz: Size, src: Location, dst: Location);
|
fn emit_add(&mut self, sz: Size, src: Location, dst: Location);
|
||||||
fn emit_sub(&mut self, sz: Size, src: Location, dst: Location);
|
fn emit_sub(&mut self, sz: Size, src: Location, dst: Location);
|
||||||
|
fn emit_neg(&mut self, sz: Size, value: Location);
|
||||||
fn emit_imul(&mut self, sz: Size, src: Location, dst: Location);
|
fn emit_imul(&mut self, sz: Size, src: Location, dst: Location);
|
||||||
fn emit_imul_imm32_gpr64(&mut self, src: u32, dst: GPR);
|
fn emit_imul_imm32_gpr64(&mut self, src: u32, dst: GPR);
|
||||||
fn emit_div(&mut self, sz: Size, divisor: Location);
|
fn emit_div(&mut self, sz: Size, divisor: Location);
|
||||||
@ -669,6 +670,19 @@ impl Emitter for Assembler {
|
|||||||
fn emit_sub(&mut self, sz: Size, src: Location, dst: Location) {
|
fn emit_sub(&mut self, sz: Size, src: Location, dst: Location) {
|
||||||
binop_all_nofp!(sub, self, sz, src, dst, { unreachable!() });
|
binop_all_nofp!(sub, self, sz, src, dst, { unreachable!() });
|
||||||
}
|
}
|
||||||
|
fn emit_neg(&mut self, sz: Size, value: Location) {
|
||||||
|
match (sz, value) {
|
||||||
|
(Size::S8, Location::GPR(value)) => { dynasm!(self ; neg Rb(value as u8)) }
|
||||||
|
(Size::S8, Location::Memory(value, disp)) => { dynasm!(self ; neg [Rq(value as u8) + disp]) }
|
||||||
|
(Size::S16, Location::GPR(value)) => { dynasm!(self ; neg Rw(value as u8)) }
|
||||||
|
(Size::S16, Location::Memory(value, disp)) => { dynasm!(self ; neg [Rq(value as u8) + disp]) }
|
||||||
|
(Size::S32, Location::GPR(value)) => { dynasm!(self ; neg Rd(value as u8)) }
|
||||||
|
(Size::S32, Location::Memory(value, disp)) => { dynasm!(self ; neg [Rq(value as u8) + disp]) }
|
||||||
|
(Size::S64, Location::GPR(value)) => { dynasm!(self ; neg Rq(value as u8)) }
|
||||||
|
(Size::S64, Location::Memory(value, disp)) => { dynasm!(self ; neg [Rq(value as u8) + disp]) }
|
||||||
|
_ => panic!("NEG {:?} {:?}", sz, value),
|
||||||
|
}
|
||||||
|
}
|
||||||
fn emit_imul(&mut self, sz: Size, src: Location, dst: Location) {
|
fn emit_imul(&mut self, sz: Size, src: Location, dst: Location) {
|
||||||
binop_gpr_gpr!(imul, self, sz, src, dst, {
|
binop_gpr_gpr!(imul, self, sz, src, dst, {
|
||||||
binop_mem_gpr!(imul, self, sz, src, dst, { unreachable!() })
|
binop_mem_gpr!(imul, self, sz, src, dst, { unreachable!() })
|
||||||
|
Reference in New Issue
Block a user