@@ -504,6 +504,33 @@ fn enc_dmb_ish() -> u32 {
504
504
0xD5033BBF
505
505
}
506
506
507
+ fn enc_ldal ( ty : Type , op : AtomicRMWOp , rs : Reg , rt : Writable < Reg > , rn : Reg ) -> u32 {
508
+ assert ! ( machreg_to_gpr( rt. to_reg( ) ) != 31 ) ;
509
+ let sz = match ty {
510
+ I64 => 0b11 ,
511
+ I32 => 0b10 ,
512
+ I16 => 0b01 ,
513
+ I8 => 0b00 ,
514
+ _ => unreachable ! ( ) ,
515
+ } ;
516
+ let op = match op {
517
+ AtomicRMWOp :: Add => 0b000 ,
518
+ AtomicRMWOp :: Clr => 0b001 ,
519
+ AtomicRMWOp :: Eor => 0b010 ,
520
+ AtomicRMWOp :: Set => 0b011 ,
521
+ AtomicRMWOp :: Smax => 0b100 ,
522
+ AtomicRMWOp :: Smin => 0b101 ,
523
+ AtomicRMWOp :: Umax => 0b110 ,
524
+ AtomicRMWOp :: Umin => 0b111 ,
525
+ } ;
526
+ 0b00_111_000_111_00000_0_000_00_00000_00000
527
+ | ( sz << 30 )
528
+ | ( machreg_to_gpr ( rs) << 16 )
529
+ | ( op << 12 )
530
+ | ( machreg_to_gpr ( rn) << 5 )
531
+ | machreg_to_gpr ( rt. to_reg ( ) )
532
+ }
533
+
507
534
fn enc_ldar ( ty : Type , rt : Writable < Reg > , rn : Reg ) -> u32 {
508
535
let sz = match ty {
509
536
I64 => 0b11 ,
@@ -1318,7 +1345,10 @@ impl MachInstEmit for Inst {
1318
1345
} => {
1319
1346
sink. put4 ( enc_ccmp_imm ( size, rn, imm, nzcv, cond) ) ;
1320
1347
}
1321
- & Inst :: AtomicRMW { ty, op } => {
1348
+ & Inst :: AtomicRMW { ty, op, rs, rt, rn } => {
1349
+ sink. put4 ( enc_ldal ( ty, op, rs, rt, rn) ) ;
1350
+ }
1351
+ & Inst :: AtomicRMWLoop { ty, op } => {
1322
1352
/* Emit this:
1323
1353
again:
1324
1354
ldaxr{,b,h} x/w27, [x25]
@@ -1340,7 +1370,7 @@ impl MachInstEmit for Inst {
1340
1370
so that we simply write in the destination, the "2nd arg for op".
1341
1371
*/
1342
1372
// TODO: We should not hardcode registers here, a better idea would be to
1343
- // pass some scratch registers in the AtomicRMW pseudo-instruction, and use those
1373
+ // pass some scratch registers in the AtomicRMWLoop pseudo-instruction, and use those
1344
1374
let xzr = zero_reg ( ) ;
1345
1375
let x24 = xreg ( 24 ) ;
1346
1376
let x25 = xreg ( 25 ) ;
0 commit comments