@@ -571,6 +571,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
571
571
.div_trunc = > try self .airBinOp (inst , .div_trunc ),
572
572
.div_floor = > try self .airBinOp (inst , .div_floor ),
573
573
.div_exact = > try self .airBinOp (inst , .div_exact ),
574
+ .rem = > try self .airBinOp (inst , .rem ),
575
+ .mod = > try self .airBinOp (inst , .mod ),
574
576
575
577
.ptr_add = > try self .airPtrArithmetic (inst , .ptr_add ),
576
578
.ptr_sub = > try self .airPtrArithmetic (inst , .ptr_sub ),
@@ -581,8 +583,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
581
583
.add_sat = > try self .airAddSat (inst ),
582
584
.sub_sat = > try self .airSubSat (inst ),
583
585
.mul_sat = > try self .airMulSat (inst ),
584
- .rem = > try self .airRem (inst ),
585
- .mod = > try self .airMod (inst ),
586
586
.shl_sat = > try self .airShlSat (inst ),
587
587
.slice = > try self .airSlice (inst ),
588
588
@@ -1731,18 +1731,6 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1731
1731
return self .finishAir (inst , result , .{ extra .lhs , extra .rhs , .none });
1732
1732
}
1733
1733
1734
- fn airRem (self : * Self , inst : Air.Inst.Index ) ! void {
1735
- const bin_op = self .air .instructions .items (.data )[inst ].bin_op ;
1736
- const result : MCValue = if (self .liveness .isUnused (inst )) .dead else return self .fail ("TODO implement rem for {}" , .{self .target .cpu .arch });
1737
- return self .finishAir (inst , result , .{ bin_op .lhs , bin_op .rhs , .none });
1738
- }
1739
-
1740
- fn airMod (self : * Self , inst : Air.Inst.Index ) ! void {
1741
- const bin_op = self .air .instructions .items (.data )[inst ].bin_op ;
1742
- const result : MCValue = if (self .liveness .isUnused (inst )) .dead else return self .fail ("TODO implement mod for {}" , .{self .target .cpu .arch });
1743
- return self .finishAir (inst , result , .{ bin_op .lhs , bin_op .rhs , .none });
1744
- }
1745
-
1746
1734
fn airShlSat (self : * Self , inst : Air.Inst.Index ) ! void {
1747
1735
const bin_op = self .air .instructions .items (.data )[inst ].bin_op ;
1748
1736
const result : MCValue = if (self .liveness .isUnused (inst )) .dead else return self .fail ("TODO implement shl_sat for {}" , .{self .target .cpu .arch });
@@ -2923,6 +2911,78 @@ fn binOp(
2923
2911
else = > unreachable ,
2924
2912
}
2925
2913
},
2914
+ .rem = > {
2915
+ switch (lhs_ty .zigTypeTag ()) {
2916
+ .Float = > return self .fail ("TODO ARM binary operations on floats" , .{}),
2917
+ .Vector = > return self .fail ("TODO ARM binary operations on vectors" , .{}),
2918
+ .Int = > {
2919
+ const mod = self .bin_file .options .module .? ;
2920
+ assert (lhs_ty .eql (rhs_ty , mod ));
2921
+ const int_info = lhs_ty .intInfo (self .target .* );
2922
+ if (int_info .bits <= 32 ) {
2923
+ switch (int_info .signedness ) {
2924
+ .signed = > {
2925
+ return self .fail ("TODO ARM signed integer mod" , .{});
2926
+ },
2927
+ .unsigned = > {
2928
+ switch (rhs ) {
2929
+ .immediate = > | imm | {
2930
+ if (std .math .isPowerOfTwo (imm )) {
2931
+ const log2 = std .math .log2_int (u32 , imm );
2932
+
2933
+ const lhs_is_register = lhs == .register ;
2934
+
2935
+ const lhs_lock : ? RegisterLock = if (lhs_is_register )
2936
+ self .register_manager .lockReg (lhs .register )
2937
+ else
2938
+ null ;
2939
+ defer if (lhs_lock ) | reg | self .register_manager .unlockReg (reg );
2940
+
2941
+ const lhs_reg = if (lhs_is_register ) lhs .register else blk : {
2942
+ const track_inst : ? Air.Inst.Index = if (metadata ) | md | inst : {
2943
+ break :inst Air .refToIndex (md .lhs ).? ;
2944
+ } else null ;
2945
+
2946
+ break :blk try self .prepareNewRegForMoving (track_inst , gp , lhs );
2947
+ };
2948
+ const new_lhs_lock = self .register_manager .lockReg (lhs_reg );
2949
+ defer if (new_lhs_lock ) | reg | self .register_manager .unlockReg (reg );
2950
+
2951
+ const dest_reg = if (metadata ) | md | blk : {
2952
+ if (lhs_is_register and self .reuseOperand (md .inst , md .lhs , 0 , lhs )) {
2953
+ break :blk lhs_reg ;
2954
+ } else {
2955
+ break :blk try self .register_manager .allocReg (md .inst , gp );
2956
+ }
2957
+ } else try self .register_manager .allocReg (null , gp );
2958
+
2959
+ if (! lhs_is_register ) try self .genSetReg (lhs_ty , lhs_reg , lhs );
2960
+
2961
+ try self .truncRegister (lhs_reg , dest_reg , int_info .signedness , log2 );
2962
+ return MCValue { .register = dest_reg };
2963
+ } else {
2964
+ return self .fail ("TODO ARM integer mod by constants" , .{});
2965
+ }
2966
+ },
2967
+ else = > return self .fail ("TODO ARM integer mod" , .{}),
2968
+ }
2969
+ },
2970
+ }
2971
+ } else {
2972
+ return self .fail ("TODO ARM integer division for integers > u32/i32" , .{});
2973
+ }
2974
+ },
2975
+ else = > unreachable ,
2976
+ }
2977
+ },
2978
+ .mod = > {
2979
+ switch (lhs_ty .zigTypeTag ()) {
2980
+ .Float = > return self .fail ("TODO ARM binary operations on floats" , .{}),
2981
+ .Vector = > return self .fail ("TODO ARM binary operations on vectors" , .{}),
2982
+ .Int = > return self .fail ("TODO ARM mod" , .{}),
2983
+ else = > unreachable ,
2984
+ }
2985
+ },
2926
2986
.addwrap ,
2927
2987
.subwrap ,
2928
2988
.mulwrap ,
0 commit comments