| ... | @@ -150,6 +150,7 @@ pub fn emitMir( | ... | @@ -150,6 +150,7 @@ pub fn emitMir( |
| 150 | .ldp => try emit.mirLoadStoreRegisterPair(inst), | 150 | .ldp => try emit.mirLoadStoreRegisterPair(inst), |
| 151 | .stp => try emit.mirLoadStoreRegisterPair(inst), | 151 | .stp => try emit.mirLoadStoreRegisterPair(inst), |
| 152 | | 152 | |
| | 153 | .ldr_ptr_stack => try emit.mirLoadStoreStack(inst), |
| 153 | .ldr_stack => try emit.mirLoadStoreStack(inst), | 154 | .ldr_stack => try emit.mirLoadStoreStack(inst), |
| 154 | .ldrb_stack => try emit.mirLoadStoreStack(inst), | 155 | .ldrb_stack => try emit.mirLoadStoreStack(inst), |
| 155 | .ldrh_stack => try emit.mirLoadStoreStack(inst), | 156 | .ldrh_stack => try emit.mirLoadStoreStack(inst), |
| ... | @@ -159,8 +160,8 @@ pub fn emitMir( | ... | @@ -159,8 +160,8 @@ pub fn emitMir( |
| 159 | .strb_stack => try emit.mirLoadStoreStack(inst), | 160 | .strb_stack => try emit.mirLoadStoreStack(inst), |
| 160 | .strh_stack => try emit.mirLoadStoreStack(inst), | 161 | .strh_stack => try emit.mirLoadStoreStack(inst), |
| 161 | | 162 | |
| 162 | .ldr_stack_argument => try emit.mirLoadStackArgument(inst), | | |
| 163 | .ldr_ptr_stack_argument => try emit.mirLoadStackArgument(inst), | 163 | .ldr_ptr_stack_argument => try emit.mirLoadStackArgument(inst), |
| | 164 | .ldr_stack_argument => try emit.mirLoadStackArgument(inst), |
| 164 | .ldrb_stack_argument => try emit.mirLoadStackArgument(inst), | 165 | .ldrb_stack_argument => try emit.mirLoadStackArgument(inst), |
| 165 | .ldrh_stack_argument => try emit.mirLoadStackArgument(inst), | 166 | .ldrh_stack_argument => try emit.mirLoadStackArgument(inst), |
| 166 | .ldrsb_stack_argument => try emit.mirLoadStackArgument(inst), | 167 | .ldrsb_stack_argument => try emit.mirLoadStackArgument(inst), |
| ... | @@ -1003,23 +1004,43 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -1003,23 +1004,43 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 1003 | const rt = load_store_stack.rt; | 1004 | const rt = load_store_stack.rt; |
| 1004 | | 1005 | |
| 1005 | const raw_offset = emit.stack_size - load_store_stack.offset; | 1006 | const raw_offset = emit.stack_size - load_store_stack.offset; |
| 1006 | const offset = switch (tag) { | 1007 | switch (tag) { |
| 1007 | .ldrb_stack, .ldrsb_stack, .strb_stack => blk: { | 1008 | .ldr_ptr_stack => { |
| 1008 | if (math.cast(u12, raw_offset)) |imm| { | 1009 | const offset = if (math.cast(u12, raw_offset)) |imm| imm else { |
| 1009 | break :blk Instruction.LoadStoreOffset.imm(imm); | 1010 | return emit.fail("TODO load stack argument ptr with larger offset", .{}); |
| 1010 | } else { | 1011 | }; |
| | 1012 | |
| | 1013 | switch (tag) { |
| | 1014 | .ldr_ptr_stack => try emit.writeInstruction(Instruction.add(rt, .sp, offset, false)), |
| | 1015 | else => unreachable, |
| | 1016 | } |
| | 1017 | }, |
| | 1018 | .ldrb_stack, .ldrsb_stack, .strb_stack => { |
| | 1019 | const offset = if (math.cast(u12, raw_offset)) |imm| Instruction.LoadStoreOffset.imm(imm) else { |
| 1011 | return emit.fail("TODO load/store stack byte with larger offset", .{}); | 1020 | return emit.fail("TODO load/store stack byte with larger offset", .{}); |
| | 1021 | }; |
| | 1022 | |
| | 1023 | switch (tag) { |
| | 1024 | .ldrb_stack => try emit.writeInstruction(Instruction.ldrb(rt, .sp, offset)), |
| | 1025 | .ldrsb_stack => try emit.writeInstruction(Instruction.ldrsb(rt, .sp, offset)), |
| | 1026 | .strb_stack => try emit.writeInstruction(Instruction.strb(rt, .sp, offset)), |
| | 1027 | else => unreachable, |
| 1012 | } | 1028 | } |
| 1013 | }, | 1029 | }, |
| 1014 | .ldrh_stack, .ldrsh_stack, .strh_stack => blk: { | 1030 | .ldrh_stack, .ldrsh_stack, .strh_stack => { |
| 1015 | assert(std.mem.isAlignedGeneric(u32, raw_offset, 2)); // misaligned stack entry | 1031 | assert(std.mem.isAlignedGeneric(u32, raw_offset, 2)); // misaligned stack entry |
| 1016 | if (math.cast(u12, @divExact(raw_offset, 2))) |imm| { | 1032 | const offset = if (math.cast(u12, @divExact(raw_offset, 2))) |imm| Instruction.LoadStoreOffset.imm(imm) else { |
| 1017 | break :blk Instruction.LoadStoreOffset.imm(imm); | | |
| 1018 | } else { | | |
| 1019 | return emit.fail("TODO load/store stack halfword with larger offset", .{}); | 1033 | return emit.fail("TODO load/store stack halfword with larger offset", .{}); |
| | 1034 | }; |
| | 1035 | |
| | 1036 | switch (tag) { |
| | 1037 | .ldrh_stack => try emit.writeInstruction(Instruction.ldrh(rt, .sp, offset)), |
| | 1038 | .ldrsh_stack => try emit.writeInstruction(Instruction.ldrsh(rt, .sp, offset)), |
| | 1039 | .strh_stack => try emit.writeInstruction(Instruction.strh(rt, .sp, offset)), |
| | 1040 | else => unreachable, |
| 1020 | } | 1041 | } |
| 1021 | }, | 1042 | }, |
| 1022 | .ldr_stack, .str_stack => blk: { | 1043 | .ldr_stack, .str_stack => { |
| 1023 | const alignment: u32 = switch (rt.size()) { | 1044 | const alignment: u32 = switch (rt.size()) { |
| 1024 | 32 => 4, | 1045 | 32 => 4, |
| 1025 | 64 => 8, | 1046 | 64 => 8, |
| ... | @@ -1027,25 +1048,17 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -1027,25 +1048,17 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 1027 | }; | 1048 | }; |
| 1028 | | 1049 | |
| 1029 | assert(std.mem.isAlignedGeneric(u32, raw_offset, alignment)); // misaligned stack entry | 1050 | assert(std.mem.isAlignedGeneric(u32, raw_offset, alignment)); // misaligned stack entry |
| 1030 | if (math.cast(u12, @divExact(raw_offset, alignment))) |imm| { | 1051 | const offset = if (math.cast(u12, @divExact(raw_offset, alignment))) |imm| Instruction.LoadStoreOffset.imm(imm) else { |
| 1031 | break :blk Instruction.LoadStoreOffset.imm(imm); | | |
| 1032 | } else { | | |
| 1033 | return emit.fail("TODO load/store stack with larger offset", .{}); | 1052 | return emit.fail("TODO load/store stack with larger offset", .{}); |
| | 1053 | }; |
| | 1054 | |
| | 1055 | switch (tag) { |
| | 1056 | .ldr_stack => try emit.writeInstruction(Instruction.ldr(rt, .sp, offset)), |
| | 1057 | .str_stack => try emit.writeInstruction(Instruction.str(rt, .sp, offset)), |
| | 1058 | else => unreachable, |
| 1034 | } | 1059 | } |
| 1035 | }, | 1060 | }, |
| 1036 | else => unreachable, | 1061 | else => unreachable, |
| 1037 | }; | | |
| 1038 | | | |
| 1039 | switch (tag) { | | |
| 1040 | .ldr_stack => try emit.writeInstruction(Instruction.ldr(rt, .sp, offset)), | | |
| 1041 | .ldrb_stack => try emit.writeInstruction(Instruction.ldrb(rt, .sp, offset)), | | |
| 1042 | .ldrh_stack => try emit.writeInstruction(Instruction.ldrh(rt, .sp, offset)), | | |
| 1043 | .ldrsb_stack => try emit.writeInstruction(Instruction.ldrsb(rt, .sp, offset)), | | |
| 1044 | .ldrsh_stack => try emit.writeInstruction(Instruction.ldrsh(rt, .sp, offset)), | | |
| 1045 | .str_stack => try emit.writeInstruction(Instruction.str(rt, .sp, offset)), | | |
| 1046 | .strb_stack => try emit.writeInstruction(Instruction.strb(rt, .sp, offset)), | | |
| 1047 | .strh_stack => try emit.writeInstruction(Instruction.strh(rt, .sp, offset)), | | |
| 1048 | else => unreachable, | | |
| 1049 | } | 1062 | } |
| 1050 | } | 1063 | } |
| 1051 | | 1064 | |