authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-05-22 15:36:45+02:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-05-22 21:02:32+02:00
logb56b4428a3a2fd8cf244580f997ec0ed2010fce2
tree0556328e5d095bcb9ab9d9c5d5f171827828cb90
parent9747303d16dfca61316a292d1e05ac901191e3a3

stage2 ARM: fix recursive fibonacci

Some handling of register_c_flag/register_v_flag was incorrect.

4 files changed, 24 insertions(+), 28 deletions(-)

src/arch/arm/CodeGen.zig+22-25
...@@ -2447,6 +2447,9 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2447,6 +2447,9 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
2447 .register_c_flag,2447 .register_c_flag,
2448 .register_v_flag,2448 .register_v_flag,
2449 => |reg| {2449 => |reg| {
2450 const reg_lock = self.register_manager.lockRegAssumeUnused(reg);
2451 defer self.register_manager.unlockReg(reg_lock);
2452
2450 switch (index) {2453 switch (index) {
2451 0 => {2454 0 => {
2452 // get wrapped value: return register2455 // get wrapped value: return register
...@@ -5062,6 +5065,7 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {...@@ -5062,6 +5065,7 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {
5062}5065}
50635066
5064fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {5067fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
5068 log.debug("genTypedValue: ty = {}, val = {}", .{ typed_value.ty.fmtDebug(), typed_value.val.fmtDebug() });
5065 if (typed_value.val.isUndef())5069 if (typed_value.val.isUndef())
5066 return MCValue{ .undef = {} };5070 return MCValue{ .undef = {} };
5067 const ptr_bits = self.target.cpu.arch.ptrBitWidth();5071 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
...@@ -5075,24 +5079,14 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -5075,24 +5079,14 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
5075 const target = self.target.*;5079 const target = self.target.*;
50765080
5077 switch (typed_value.ty.zigTypeTag()) {5081 switch (typed_value.ty.zigTypeTag()) {
5078 .Array => {
5079 return self.lowerUnnamedConst(typed_value);
5080 },
5081 .Pointer => switch (typed_value.ty.ptrSize()) {5082 .Pointer => switch (typed_value.ty.ptrSize()) {
5082 .Slice => {5083 .Slice => {},
5083 return self.lowerUnnamedConst(typed_value);
5084 },
5085 else => {5084 else => {
5086 switch (typed_value.val.tag()) {5085 switch (typed_value.val.tag()) {
5087 .int_u64 => {5086 .int_u64 => {
5088 return MCValue{ .immediate = @intCast(u32, typed_value.val.toUnsignedInt(target)) };5087 return MCValue{ .immediate = @intCast(u32, typed_value.val.toUnsignedInt(target)) };
5089 },5088 },
5090 .slice => {5089 else => {},
5091 return self.lowerUnnamedConst(typed_value);
5092 },
5093 else => {
5094 return self.fail("TODO codegen more kinds of const pointers", .{});
5095 },
5096 }5090 }
5097 },5091 },
5098 },5092 },
...@@ -5115,8 +5109,6 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -5115,8 +5109,6 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
5115 .Bool => {5109 .Bool => {
5116 return MCValue{ .immediate = @boolToInt(typed_value.val.toBool()) };5110 return MCValue{ .immediate = @boolToInt(typed_value.val.toBool()) };
5117 },5111 },
5118 .ComptimeInt => unreachable, // semantic analysis prevents this
5119 .ComptimeFloat => unreachable, // semantic analysis prevents this
5120 .Optional => {5112 .Optional => {
5121 if (typed_value.ty.isPtrLikeOptional()) {5113 if (typed_value.ty.isPtrLikeOptional()) {
5122 if (typed_value.val.isNull())5114 if (typed_value.val.isNull())
...@@ -5130,7 +5122,6 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -5130,7 +5122,6 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
5130 } else if (typed_value.ty.abiSize(self.target.*) == 1) {5122 } else if (typed_value.ty.abiSize(self.target.*) == 1) {
5131 return MCValue{ .immediate = @boolToInt(typed_value.val.isNull()) };5123 return MCValue{ .immediate = @boolToInt(typed_value.val.isNull()) };
5132 }5124 }
5133 return self.fail("TODO non pointer optionals", .{});
5134 },5125 },
5135 .Enum => {5126 .Enum => {
5136 if (typed_value.val.castTag(.enum_field_index)) |field_index| {5127 if (typed_value.val.castTag(.enum_field_index)) |field_index| {
...@@ -5166,28 +5157,34 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -5166,28 +5157,34 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
5166 const error_type = typed_value.ty.errorUnionSet();5157 const error_type = typed_value.ty.errorUnionSet();
5167 const payload_type = typed_value.ty.errorUnionPayload();5158 const payload_type = typed_value.ty.errorUnionPayload();
51685159
5169 if (typed_value.val.castTag(.eu_payload)) |pl| {5160 if (typed_value.val.castTag(.eu_payload)) |_| {
5170 if (!payload_type.hasRuntimeBits()) {5161 if (!payload_type.hasRuntimeBits()) {
5171 // We use the error type directly as the type.5162 // We use the error type directly as the type.
5172 return MCValue{ .immediate = 0 };5163 return MCValue{ .immediate = 0 };
5173 }5164 }
5174
5175 _ = pl;
5176 return self.fail("TODO implement error union const of type '{}' (non-error)", .{typed_value.ty.fmtDebug()});
5177 } else {5165 } else {
5178 if (!payload_type.hasRuntimeBits()) {5166 if (!payload_type.hasRuntimeBits()) {
5179 // We use the error type directly as the type.5167 // We use the error type directly as the type.
5180 return self.genTypedValue(.{ .ty = error_type, .val = typed_value.val });5168 return self.genTypedValue(.{ .ty = error_type, .val = typed_value.val });
5181 }5169 }
5182
5183 return self.fail("TODO implement error union const of type '{}' (error)", .{typed_value.ty.fmtDebug()});
5184 }5170 }
5185 },5171 },
5186 .Struct => {5172
5187 return self.lowerUnnamedConst(typed_value);5173 .ComptimeInt => unreachable, // semantic analysis prevents this
5188 },5174 .ComptimeFloat => unreachable, // semantic analysis prevents this
5189 else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty.fmtDebug()}),5175 .Type => unreachable,
5176 .EnumLiteral => unreachable,
5177 .Void => unreachable,
5178 .NoReturn => unreachable,
5179 .Undefined => unreachable,
5180 .Null => unreachable,
5181 .BoundFn => unreachable,
5182 .Opaque => unreachable,
5183
5184 else => {},
5190 }5185 }
5186
5187 return self.lowerUnnamedConst(typed_value);
5191}5188}
51925189
5193const CallMCValues = struct {5190const CallMCValues = struct {
src/arch/arm/Emit.zig+1-1
...@@ -394,7 +394,7 @@ fn mirDataProcessing(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -394,7 +394,7 @@ fn mirDataProcessing(emit: *Emit, inst: Mir.Inst.Index) !void {
394 .orr => try emit.writeInstruction(Instruction.orr(cond, rr_op.rd, rr_op.rn, rr_op.op)),394 .orr => try emit.writeInstruction(Instruction.orr(cond, rr_op.rd, rr_op.rn, rr_op.op)),
395 .rsb => try emit.writeInstruction(Instruction.rsb(cond, rr_op.rd, rr_op.rn, rr_op.op)),395 .rsb => try emit.writeInstruction(Instruction.rsb(cond, rr_op.rd, rr_op.rn, rr_op.op)),
396 .sub => try emit.writeInstruction(Instruction.sub(cond, rr_op.rd, rr_op.rn, rr_op.op)),396 .sub => try emit.writeInstruction(Instruction.sub(cond, rr_op.rd, rr_op.rn, rr_op.op)),
397 .subs => try emit.writeInstruction(Instruction.sub(cond, rr_op.rd, rr_op.rn, rr_op.op)),397 .subs => try emit.writeInstruction(Instruction.subs(cond, rr_op.rd, rr_op.rn, rr_op.op)),
398 else => unreachable,398 else => unreachable,
399 }399 }
400}400}
test/behavior/underscore.zig-1
...@@ -7,7 +7,6 @@ test "ignore lval with underscore" {...@@ -7,7 +7,6 @@ test "ignore lval with underscore" {
7}7}
88
9test "ignore lval with underscore (while loop)" {9test "ignore lval with underscore (while loop)" {
10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
11 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;10 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1211
13 while (optionalReturnError()) |_| {12 while (optionalReturnError()) |_| {
test/cases/recursive_fibonacci.zig+1-1
...@@ -20,5 +20,5 @@ fn assert(ok: bool) void {...@@ -20,5 +20,5 @@ fn assert(ok: bool) void {
20}20}
2121
22// run22// run
23// target=x86_64-linux,x86_64-macos,wasm32-wasi23// target=x86_64-linux,x86_64-macos,arm-linux,wasm32-wasi
24//24//