(
fgen: &mut FunctionGenerator,
builder: &mut FunctionBuilder,
_: Opcode,
_: &[Type],
rets: &[Type],
)
| 331 | } |
| 332 | |
| 333 | fn insert_atomic_rmw( |
| 334 | fgen: &mut FunctionGenerator, |
| 335 | builder: &mut FunctionBuilder, |
| 336 | _: Opcode, |
| 337 | _: &[Type], |
| 338 | rets: &[Type], |
| 339 | ) -> Result<()> { |
| 340 | let ctrl_type = *rets.first().unwrap(); |
| 341 | let type_size = ctrl_type.bytes(); |
| 342 | |
| 343 | let rmw_op = *fgen.u.choose(AtomicRmwOp::all())?; |
| 344 | |
| 345 | let (address, flags, offset) = fgen.generate_address_and_memflags(builder, type_size, true)?; |
| 346 | |
| 347 | // AtomicRMW does not directly support offsets, so add the offset to the address separately. |
| 348 | let address = builder.ins().iadd_imm(address, i64::from(offset)); |
| 349 | |
| 350 | // Load and store target variables |
| 351 | let source_var = fgen.get_variable_of_type(ctrl_type)?; |
| 352 | let target_var = fgen.get_variable_of_type(ctrl_type)?; |
| 353 | |
| 354 | let source_val = builder.use_var(source_var); |
| 355 | let new_val = builder |
| 356 | .ins() |
| 357 | .atomic_rmw(ctrl_type, flags, rmw_op, address, source_val); |
| 358 | |
| 359 | builder.def_var(target_var, new_val); |
| 360 | Ok(()) |
| 361 | } |
| 362 | |
| 363 | fn insert_atomic_cas( |
| 364 | fgen: &mut FunctionGenerator, |
nothing calls this directly
no test coverage detected