| ... | @@ -96,6 +96,9 @@ stack: std.AutoHashMapUnmanaged(u32, StackAllocation) = .{}, | ... | @@ -96,6 +96,9 @@ stack: std.AutoHashMapUnmanaged(u32, StackAllocation) = .{}, |
| 96 | /// Tracks the current instruction allocated to the condition flags | 96 | /// Tracks the current instruction allocated to the condition flags |
| 97 | condition_flags_inst: ?Air.Inst.Index = null, | 97 | condition_flags_inst: ?Air.Inst.Index = null, |
| 98 | | 98 | |
| | 99 | /// Tracks the current instruction allocated to the condition register |
| | 100 | condition_register_inst: ?Air.Inst.Index = null, |
| | 101 | |
| 99 | /// Offset from the stack base, representing the end of the stack frame. | 102 | /// Offset from the stack base, representing the end of the stack frame. |
| 100 | max_end_stack: u32 = 0, | 103 | max_end_stack: u32 = 0, |
| 101 | /// Represents the current end stack offset. If there is no existing slot | 104 | /// Represents the current end stack offset. If there is no existing slot |
| ... | @@ -148,6 +151,13 @@ const MCValue = union(enum) { | ... | @@ -148,6 +151,13 @@ const MCValue = union(enum) { |
| 148 | cond: Instruction.Condition, | 151 | cond: Instruction.Condition, |
| 149 | ccr: Instruction.CCR, | 152 | ccr: Instruction.CCR, |
| 150 | }, | 153 | }, |
| | 154 | /// The value is in the specified Register. The value is 1 (if |
| | 155 | /// the type is u1) or true (if the type in bool) iff the |
| | 156 | /// specified condition is true. |
| | 157 | condition_register: struct { |
| | 158 | cond: Instruction.RCondition, |
| | 159 | reg: Register, |
| | 160 | }, |
| 151 | | 161 | |
| 152 | fn isMemory(mcv: MCValue) bool { | 162 | fn isMemory(mcv: MCValue) bool { |
| 153 | return switch (mcv) { | 163 | return switch (mcv) { |
| ... | @@ -171,6 +181,8 @@ const MCValue = union(enum) { | ... | @@ -171,6 +181,8 @@ const MCValue = union(enum) { |
| 171 | | 181 | |
| 172 | .immediate, | 182 | .immediate, |
| 173 | .memory, | 183 | .memory, |
| | 184 | .condition_flags, |
| | 185 | .condition_register, |
| 174 | .ptr_stack_offset, | 186 | .ptr_stack_offset, |
| 175 | .undef, | 187 | .undef, |
| 176 | => false, | 188 | => false, |
| ... | @@ -1748,7 +1760,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1748,7 +1760,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 1748 | _ = try self.addInst(.{ | 1760 | _ = try self.addInst(.{ |
| 1749 | .tag = .movcc, | 1761 | .tag = .movcc, |
| 1750 | .data = .{ | 1762 | .data = .{ |
| 1751 | .conditional_move = .{ | 1763 | .conditional_move_int = .{ |
| 1752 | .ccr = rwo.flag.ccr, | 1764 | .ccr = rwo.flag.ccr, |
| 1753 | .cond = .{ .icond = rwo.flag.cond }, | 1765 | .cond = .{ .icond = rwo.flag.cond }, |
| 1754 | .is_imm = true, | 1766 | .is_imm = true, |
| ... | @@ -2401,6 +2413,17 @@ fn condBr(self: *Self, condition: MCValue) !Mir.Inst.Index { | ... | @@ -2401,6 +2413,17 @@ fn condBr(self: *Self, condition: MCValue) !Mir.Inst.Index { |
| 2401 | }, | 2413 | }, |
| 2402 | }, | 2414 | }, |
| 2403 | }), | 2415 | }), |
| | 2416 | .condition_register => |reg| try self.addInst(.{ |
| | 2417 | .tag = .bpr, |
| | 2418 | .data = .{ |
| | 2419 | .branch_predict_reg = .{ |
| | 2420 | .rs1 = reg.reg, |
| | 2421 | // Here we map to the opposite condition because the jump is to the false branch. |
| | 2422 | .cond = reg.cond.negate(), |
| | 2423 | .inst = undefined, // Will be filled by performReloc |
| | 2424 | }, |
| | 2425 | }, |
| | 2426 | }), |
| 2404 | else => blk: { | 2427 | else => blk: { |
| 2405 | const reg = switch (condition) { | 2428 | const reg = switch (condition) { |
| 2406 | .register => |r| r, | 2429 | .register => |r| r, |
| ... | @@ -2655,7 +2678,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -2655,7 +2678,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 2655 | _ = try self.addInst(.{ | 2678 | _ = try self.addInst(.{ |
| 2656 | .tag = .movcc, | 2679 | .tag = .movcc, |
| 2657 | .data = .{ | 2680 | .data = .{ |
| 2658 | .conditional_move = .{ | 2681 | .conditional_move_int = .{ |
| 2659 | .ccr = ccr, | 2682 | .ccr = ccr, |
| 2660 | .cond = condition, | 2683 | .cond = condition, |
| 2661 | .is_imm = true, | 2684 | .is_imm = true, |
| ... | @@ -2665,6 +2688,34 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -2665,6 +2688,34 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 2665 | }, | 2688 | }, |
| 2666 | }); | 2689 | }); |
| 2667 | }, | 2690 | }, |
| | 2691 | .condition_register => |op| { |
| | 2692 | const condition = op.cond; |
| | 2693 | const register = op.reg; |
| | 2694 | |
| | 2695 | _ = try self.addInst(.{ |
| | 2696 | .tag = .mov, |
| | 2697 | .data = .{ |
| | 2698 | .arithmetic_2op = .{ |
| | 2699 | .is_imm = false, |
| | 2700 | .rs1 = reg, |
| | 2701 | .rs2_or_imm = .{ .rs2 = .g0 }, |
| | 2702 | }, |
| | 2703 | }, |
| | 2704 | }); |
| | 2705 | |
| | 2706 | _ = try self.addInst(.{ |
| | 2707 | .tag = .movr, |
| | 2708 | .data = .{ |
| | 2709 | .conditional_move_reg = .{ |
| | 2710 | .cond = condition, |
| | 2711 | .is_imm = true, |
| | 2712 | .rd = reg, |
| | 2713 | .rs1 = register, |
| | 2714 | .rs2_or_imm = .{ .imm = 1 }, |
| | 2715 | }, |
| | 2716 | }, |
| | 2717 | }); |
| | 2718 | }, |
| 2668 | .undef => { | 2719 | .undef => { |
| 2669 | if (!self.wantSafety()) | 2720 | if (!self.wantSafety()) |
| 2670 | return; // The already existing value will do just fine. | 2721 | return; // The already existing value will do just fine. |
| ... | @@ -2832,6 +2883,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -2832,6 +2883,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 2832 | } | 2883 | } |
| 2833 | }, | 2884 | }, |
| 2834 | .condition_flags, | 2885 | .condition_flags, |
| | 2886 | .condition_register, |
| 2835 | .immediate, | 2887 | .immediate, |
| 2836 | .ptr_stack_offset, | 2888 | .ptr_stack_offset, |
| 2837 | => { | 2889 | => { |
| ... | @@ -2872,7 +2924,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -2872,7 +2924,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 2872 | _ = try self.addInst(.{ | 2924 | _ = try self.addInst(.{ |
| 2873 | .tag = .movcc, | 2925 | .tag = .movcc, |
| 2874 | .data = .{ | 2926 | .data = .{ |
| 2875 | .conditional_move = .{ | 2927 | .conditional_move_int = .{ |
| 2876 | .ccr = rwo.flag.ccr, | 2928 | .ccr = rwo.flag.ccr, |
| 2877 | .cond = .{ .icond = rwo.flag.cond }, | 2929 | .cond = .{ .icond = rwo.flag.cond }, |
| 2878 | .is_imm = true, | 2930 | .is_imm = true, |
| ... | @@ -3124,6 +3176,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -3124,6 +3176,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 3124 | .unreach => unreachable, | 3176 | .unreach => unreachable, |
| 3125 | .dead => unreachable, | 3177 | .dead => unreachable, |
| 3126 | .condition_flags, | 3178 | .condition_flags, |
| | 3179 | .condition_register, |
| 3127 | .register_with_overflow, | 3180 | .register_with_overflow, |
| 3128 | => unreachable, // cannot hold an address | 3181 | => unreachable, // cannot hold an address |
| 3129 | .immediate => |imm| try self.setRegOrMem(elem_ty, dst_mcv, .{ .memory = imm }), | 3182 | .immediate => |imm| try self.setRegOrMem(elem_ty, dst_mcv, .{ .memory = imm }), |
| ... | @@ -3475,6 +3528,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3475,6 +3528,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3475 | .unreach => unreachable, | 3528 | .unreach => unreachable, |
| 3476 | .dead => unreachable, | 3529 | .dead => unreachable, |
| 3477 | .condition_flags, | 3530 | .condition_flags, |
| | 3531 | .condition_register, |
| 3478 | .register_with_overflow, | 3532 | .register_with_overflow, |
| 3479 | => unreachable, // cannot hold an address | 3533 | => unreachable, // cannot hold an address |
| 3480 | .immediate => |imm| { | 3534 | .immediate => |imm| { |