| author | |
| committer | |
| log | 71923d7e400e0e5e5b1f935c1f089f34b9d922ea |
| tree | 362af302cba25a78d169585b94419cc94c31e358 |
| parent | 6b8e33d14c92229b1632c481906d7d698c584000 |
| parent | 8a0e86cd5cfd13792ce74ebac7a0cd20fb9e3c11 |
| signature |
stage2 ARM: Implement airLoad for slices2 files changed, 70 insertions(+), 2 deletions(-)
src/arch/arm/CodeGen.zig+31-2| ... | @@ -1317,8 +1317,37 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -1317,8 +1317,37 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 1317 | .stack_offset => |off| { | 1317 | .stack_offset => |off| { |
| 1318 | if (elem_ty.abiSize(self.target.*) <= 4) { | 1318 | if (elem_ty.abiSize(self.target.*) <= 4) { |
| 1319 | const tmp_reg = try self.register_manager.allocReg(null, &.{}); | 1319 | const tmp_reg = try self.register_manager.allocReg(null, &.{}); |
| 1320 | try self.load(.{ .register = tmp_reg }, ptr, elem_ty); | 1320 | try self.load(.{ .register = tmp_reg }, ptr, ptr_ty); |
| 1321 | return self.genSetStack(elem_ty, off, MCValue{ .register = tmp_reg }); | 1321 | try self.genSetStack(elem_ty, off, MCValue{ .register = tmp_reg }); |
| 1322 | } else if (elem_ty.abiSize(self.target.*) == 8) { | ||
| 1323 | // TODO generalize this: maybe add a | ||
| 1324 | // genArmMemcpy function which manually copies | ||
| 1325 | // data if the size is below a certain | ||
| 1326 | // threshold and calls "memcpy" if the size is | ||
| 1327 | // larger | ||
| 1328 | |||
| 1329 | const usize_ty = Type.initTag(.usize); | ||
| 1330 | const tmp_regs = try self.register_manager.allocRegs(2, .{ null, null }, &.{}); | ||
| 1331 | _ = try self.addInst(.{ | ||
| 1332 | .tag = .ldr, | ||
| 1333 | .cond = .al, | ||
| 1334 | .data = .{ .rr_offset = .{ | ||
| 1335 | .rt = tmp_regs[0], | ||
| 1336 | .rn = reg, | ||
| 1337 | .offset = .{ .offset = Instruction.Offset.none }, | ||
| 1338 | } }, | ||
| 1339 | }); | ||
| 1340 | _ = try self.addInst(.{ | ||
| 1341 | .tag = .ldr, | ||
| 1342 | .cond = .al, | ||
| 1343 | .data = .{ .rr_offset = .{ | ||
| 1344 | .rt = tmp_regs[1], | ||
| 1345 | .rn = reg, | ||
| 1346 | .offset = .{ .offset = Instruction.Offset.imm(4) }, | ||
| 1347 | } }, | ||
| 1348 | }); | ||
| 1349 | try self.genSetStack(usize_ty, off, MCValue{ .register = tmp_regs[0] }); | ||
| 1350 | try self.genSetStack(usize_ty, off + 4, MCValue{ .register = tmp_regs[1] }); | ||
| 1322 | } else { | 1351 | } else { |
| 1323 | return self.fail("TODO implement memcpy", .{}); | 1352 | return self.fail("TODO implement memcpy", .{}); |
| 1324 | } | 1353 | } |
src/codegen.zig+39| ... | @@ -150,6 +150,13 @@ pub fn generateSymbol( | ... | @@ -150,6 +150,13 @@ pub fn generateSymbol( |
| 150 | const tracy = trace(@src()); | 150 | const tracy = trace(@src()); |
| 151 | defer tracy.end(); | 151 | defer tracy.end(); |
| 152 | 152 | ||
| 153 | if (typed_value.val.isUndefDeep()) { | ||
| 154 | const target = bin_file.options.target; | ||
| 155 | const abi_size = try math.cast(usize, typed_value.ty.abiSize(target)); | ||
| 156 | try code.appendNTimes(0xaa, abi_size); | ||
| 157 | return Result{ .appended = {} }; | ||
| 158 | } | ||
| 159 | |||
| 153 | switch (typed_value.ty.zigTypeTag()) { | 160 | switch (typed_value.ty.zigTypeTag()) { |
| 154 | .Fn => { | 161 | .Fn => { |
| 155 | return Result{ | 162 | return Result{ |
| ... | @@ -193,6 +200,38 @@ pub fn generateSymbol( | ... | @@ -193,6 +200,38 @@ pub fn generateSymbol( |
| 193 | }, | 200 | }, |
| 194 | .Pointer => switch (typed_value.ty.ptrSize()) { | 201 | .Pointer => switch (typed_value.ty.ptrSize()) { |
| 195 | .Slice => { | 202 | .Slice => { |
| 203 | // TODO populate .debug_info for the slice | ||
| 204 | |||
| 205 | // generate ptr | ||
| 206 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | ||
| 207 | const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf); | ||
| 208 | switch (try generateSymbol(bin_file, src_loc, .{ | ||
| 209 | .ty = slice_ptr_field_type, | ||
| 210 | .val = typed_value.val.slicePtr(), | ||
| 211 | }, code, debug_output)) { | ||
| 212 | .appended => {}, | ||
| 213 | .externally_managed => |slice| { | ||
| 214 | code.appendSliceAssumeCapacity(slice); | ||
| 215 | }, | ||
| 216 | .fail => |em| return Result{ .fail = em }, | ||
| 217 | } | ||
| 218 | |||
| 219 | // generate length | ||
| 220 | var int_buffer: Value.Payload.U64 = .{ | ||
| 221 | .base = .{ .tag = .int_u64 }, | ||
| 222 | .data = typed_value.val.sliceLen(), | ||
| 223 | }; | ||
| 224 | switch (try generateSymbol(bin_file, src_loc, .{ | ||
| 225 | .ty = Type.initTag(.usize), | ||
| 226 | .val = Value.initPayload(&int_buffer.base), | ||
| 227 | }, code, debug_output)) { | ||
| 228 | .appended => {}, | ||
| 229 | .externally_managed => |slice| { | ||
| 230 | code.appendSliceAssumeCapacity(slice); | ||
| 231 | }, | ||
| 232 | .fail => |em| return Result{ .fail = em }, | ||
| 233 | } | ||
| 234 | |||
| 196 | return Result{ | 235 | return Result{ |
| 197 | .fail = try ErrorMsg.create( | 236 | .fail = try ErrorMsg.create( |
| 198 | bin_file.allocator, | 237 | bin_file.allocator, |