@@ -677,8 +677,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
677
677
.prefetch = > try self .airPrefetch (inst ),
678
678
.mul_add = > try self .airMulAdd (inst ),
679
679
680
- .@"try" = > @panic ( "TODO" ),
681
- .try_ptr = > @panic ( "TODO" ),
680
+ .@"try" = > try self . airTry ( inst ),
681
+ .try_ptr = > try self . airTryPtr ( inst ),
682
682
683
683
.dbg_var_ptr ,
684
684
.dbg_var_val ,
@@ -1837,8 +1837,8 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
1837
1837
const ty_op = self .air .instructions .items (.data )[inst ].ty_op ;
1838
1838
const result : MCValue = if (self .liveness .isUnused (inst )) .dead else result : {
1839
1839
const error_union_ty = self .air .typeOf (ty_op .operand );
1840
- const mcv = try self .resolveInst (ty_op .operand );
1841
- break :result try self .errUnionPayload (mcv , error_union_ty );
1840
+ const error_union = try self .resolveInst (ty_op .operand );
1841
+ break :result try self .errUnionPayload (error_union , error_union_ty );
1842
1842
};
1843
1843
return self .finishAir (inst , result , .{ ty_op .operand , .none , .none });
1844
1844
}
@@ -3705,6 +3705,42 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
3705
3705
return self .finishAir (inst , .dead , .{ operand , .none , .none });
3706
3706
}
3707
3707
3708
+ /// Given a boolean condition, emit a jump that is taken when that
3709
+ /// condition is false.
3710
+ fn condBr (self : * Self , condition : MCValue ) ! Mir.Inst.Index {
3711
+ const condition_code : Condition = switch (condition ) {
3712
+ .cpsr_flags = > | cond | cond .negate (),
3713
+ else = > blk : {
3714
+ const reg = switch (condition ) {
3715
+ .register = > | r | r ,
3716
+ else = > try self .copyToTmpRegister (Type .bool , condition ),
3717
+ };
3718
+
3719
+ try self .spillCompareFlagsIfOccupied ();
3720
+
3721
+ // cmp reg, 1
3722
+ // bne ...
3723
+ _ = try self .addInst (.{
3724
+ .tag = .cmp ,
3725
+ .cond = .al ,
3726
+ .data = .{ .rr_op = .{
3727
+ .rd = .r0 ,
3728
+ .rn = reg ,
3729
+ .op = Instruction .Operand .imm (1 , 0 ),
3730
+ } },
3731
+ });
3732
+
3733
+ break :blk .ne ;
3734
+ },
3735
+ };
3736
+
3737
+ return try self .addInst (.{
3738
+ .tag = .b ,
3739
+ .cond = condition_code ,
3740
+ .data = .{ .inst = undefined }, // populated later through performReloc
3741
+ });
3742
+ }
3743
+
3708
3744
fn airCondBr (self : * Self , inst : Air.Inst.Index ) ! void {
3709
3745
const pl_op = self .air .instructions .items (.data )[inst ].pl_op ;
3710
3746
const cond_inst = try self .resolveInst (pl_op .operand );
@@ -3713,39 +3749,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
3713
3749
const else_body = self .air .extra [extra .end + then_body .len .. ][0.. extra .data .else_body_len ];
3714
3750
const liveness_condbr = self .liveness .getCondBr (inst );
3715
3751
3716
- const reloc : Mir.Inst.Index = reloc : {
3717
- const condition : Condition = switch (cond_inst ) {
3718
- .cpsr_flags = > | cond | cond .negate (),
3719
- else = > blk : {
3720
- const reg = switch (cond_inst ) {
3721
- .register = > | r | r ,
3722
- else = > try self .copyToTmpRegister (Type .bool , cond_inst ),
3723
- };
3724
-
3725
- try self .spillCompareFlagsIfOccupied ();
3726
-
3727
- // cmp reg, 1
3728
- // bne ...
3729
- _ = try self .addInst (.{
3730
- .tag = .cmp ,
3731
- .cond = .al ,
3732
- .data = .{ .rr_op = .{
3733
- .rd = .r0 ,
3734
- .rn = reg ,
3735
- .op = Instruction .Operand .imm (1 , 0 ),
3736
- } },
3737
- });
3738
-
3739
- break :blk .ne ;
3740
- },
3741
- };
3742
-
3743
- break :reloc try self .addInst (.{
3744
- .tag = .b ,
3745
- .cond = condition ,
3746
- .data = .{ .inst = undefined }, // populated later through performReloc
3747
- });
3748
- };
3752
+ const reloc : Mir.Inst.Index = try self .condBr (cond_inst );
3749
3753
3750
3754
// If the condition dies here in this condbr instruction, process
3751
3755
// that death now instead of later as this has an effect on
@@ -4157,13 +4161,8 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
4157
4161
.lhs = condition ,
4158
4162
.rhs = item ,
4159
4163
} };
4160
- const cmp_result = try self .cmp (operands , condition_ty , .neq );
4161
-
4162
- relocs [0 ] = try self .addInst (.{
4163
- .tag = .b ,
4164
- .cond = cmp_result .cpsr_flags ,
4165
- .data = .{ .inst = undefined }, // populated later through performReloc
4166
- });
4164
+ const cmp_result = try self .cmp (operands , condition_ty , .eq );
4165
+ relocs [0 ] = try self .condBr (cmp_result );
4167
4166
} else {
4168
4167
return self .fail ("TODO switch with multiple items" , .{});
4169
4168
}
@@ -5148,6 +5147,33 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
5148
5147
return self .finishAir (inst , result , .{ extra .lhs , extra .rhs , pl_op .operand });
5149
5148
}
5150
5149
5150
+ fn airTry (self : * Self , inst : Air.Inst.Index ) ! void {
5151
+ const pl_op = self .air .instructions .items (.data )[inst ].pl_op ;
5152
+ const extra = self .air .extraData (Air .Try , pl_op .payload );
5153
+ const body = self .air .extra [extra .end .. ][0.. extra .data .body_len ];
5154
+ const result : MCValue = result : {
5155
+ const error_union_ty = self .air .typeOf (pl_op .operand );
5156
+ const error_union = try self .resolveInst (pl_op .operand );
5157
+ const is_err_result = try self .isErr (error_union_ty , error_union );
5158
+ const reloc = try self .condBr (is_err_result );
5159
+
5160
+ try self .genBody (body );
5161
+
5162
+ try self .performReloc (reloc );
5163
+ break :result try self .errUnionPayload (error_union , error_union_ty );
5164
+ };
5165
+ return self .finishAir (inst , result , .{ pl_op .operand , .none , .none });
5166
+ }
5167
+
5168
+ fn airTryPtr (self : * Self , inst : Air.Inst.Index ) ! void {
5169
+ const ty_pl = self .air .instructions .items (.data )[inst ].ty_pl ;
5170
+ const extra = self .air .extraData (Air .TryPtr , ty_pl .payload );
5171
+ const body = self .air .extra [extra .end .. ][0.. extra .data .body_len ];
5172
+ _ = body ;
5173
+ return self .fail ("TODO implement airTryPtr for arm" , .{});
5174
+ // return self.finishAir(inst, result, .{ extra.data.ptr, .none, .none });
5175
+ }
5176
+
5151
5177
fn resolveInst (self : * Self , inst : Air.Inst.Ref ) InnerError ! MCValue {
5152
5178
// First section of indexes correspond to a set number of constant values.
5153
5179
const ref_int = @enumToInt (inst );
0 commit comments