| ... | @@ -1308,6 +1308,15 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -1308,6 +1308,15 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 1308 | } }, | 1308 | } }, |
| 1309 | }); | 1309 | }); |
| 1310 | }, | 1310 | }, |
| | 1311 | .stack_offset => |off| { |
| | 1312 | if (elem_ty.abiSize(self.target.*) <= 4) { |
| | 1313 | const tmp_reg = try self.register_manager.allocReg(null, &.{}); |
| | 1314 | try self.load(.{ .register = tmp_reg }, ptr, elem_ty); |
| | 1315 | return self.genSetStack(elem_ty, off, MCValue{ .register = tmp_reg }); |
| | 1316 | } else { |
| | 1317 | return self.fail("TODO implement memcpy", .{}); |
| | 1318 | } |
| | 1319 | }, |
| 1311 | else => return self.fail("TODO load from register into {}", .{dst_mcv}), | 1320 | else => return self.fail("TODO load from register into {}", .{dst_mcv}), |
| 1312 | } | 1321 | } |
| 1313 | }, | 1322 | }, |
| ... | @@ -1351,11 +1360,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1351,11 +1360,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 1351 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 1360 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1352 | } | 1361 | } |
| 1353 | | 1362 | |
| 1354 | fn airStore(self: *Self, inst: Air.Inst.Index) !void { | 1363 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { |
| 1355 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | | |
| 1356 | const ptr = try self.resolveInst(bin_op.lhs); | | |
| 1357 | const value = try self.resolveInst(bin_op.rhs); | | |
| 1358 | const elem_ty = self.air.typeOf(bin_op.rhs); | | |
| 1359 | switch (ptr) { | 1364 | switch (ptr) { |
| 1360 | .none => unreachable, | 1365 | .none => unreachable, |
| 1361 | .undef => unreachable, | 1366 | .undef => unreachable, |
| ... | @@ -1365,27 +1370,62 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1365,27 +1370,62 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void { |
| 1365 | .compare_flags_signed => unreachable, | 1370 | .compare_flags_signed => unreachable, |
| 1366 | .stack_argument_offset => unreachable, | 1371 | .stack_argument_offset => unreachable, |
| 1367 | .immediate => |imm| { | 1372 | .immediate => |imm| { |
| 1368 | try self.setRegOrMem(elem_ty, .{ .memory = imm }, value); | 1373 | try self.setRegOrMem(value_ty, .{ .memory = imm }, value); |
| 1369 | }, | 1374 | }, |
| 1370 | .ptr_stack_offset => |off| { | 1375 | .ptr_stack_offset => |off| { |
| 1371 | try self.genSetStack(elem_ty, off, value); | 1376 | try self.genSetStack(value_ty, off, value); |
| 1372 | }, | 1377 | }, |
| 1373 | .ptr_embedded_in_code => |off| { | 1378 | .ptr_embedded_in_code => |off| { |
| 1374 | try self.setRegOrMem(elem_ty, .{ .embedded_in_code = off }, value); | 1379 | try self.setRegOrMem(value_ty, .{ .embedded_in_code = off }, value); |
| 1375 | }, | 1380 | }, |
| 1376 | .embedded_in_code => { | 1381 | .embedded_in_code => { |
| 1377 | return self.fail("TODO implement storing to MCValue.embedded_in_code", .{}); | 1382 | return self.fail("TODO implement storing to MCValue.embedded_in_code", .{}); |
| 1378 | }, | 1383 | }, |
| 1379 | .register => { | 1384 | .register => |addr_reg| { |
| 1380 | return self.fail("TODO implement storing to MCValue.register", .{}); | 1385 | switch (value) { |
| | 1386 | .register => |value_reg| { |
| | 1387 | _ = try self.addInst(.{ |
| | 1388 | .tag = .str, |
| | 1389 | .cond = .al, |
| | 1390 | .data = .{ .rr_offset = .{ |
| | 1391 | .rt = value_reg, |
| | 1392 | .rn = addr_reg, |
| | 1393 | .offset = .{ .offset = Instruction.Offset.none }, |
| | 1394 | } }, |
| | 1395 | }); |
| | 1396 | }, |
| | 1397 | else => { |
| | 1398 | if (value_ty.abiSize(self.target.*) <= 4) { |
| | 1399 | const tmp_reg = try self.register_manager.allocReg(null, &.{addr_reg}); |
| | 1400 | try self.genSetReg(value_ty, tmp_reg, value); |
| | 1401 | |
| | 1402 | try self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty); |
| | 1403 | } else { |
| | 1404 | return self.fail("TODO implement memcpy", .{}); |
| | 1405 | } |
| | 1406 | }, |
| | 1407 | } |
| 1381 | }, | 1408 | }, |
| 1382 | .memory => { | 1409 | .memory => { |
| | 1410 | // const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr); |
| | 1411 | // try self.store(.{ .register = addr_reg }, value, ptr_ty, value_ty); |
| 1383 | return self.fail("TODO implement storing to MCValue.memory", .{}); | 1412 | return self.fail("TODO implement storing to MCValue.memory", .{}); |
| 1384 | }, | 1413 | }, |
| 1385 | .stack_offset => { | 1414 | .stack_offset => { |
| 1386 | return self.fail("TODO implement storing to MCValue.stack_offset", .{}); | 1415 | return self.fail("TODO implement storing to MCValue.stack_offset", .{}); |
| 1387 | }, | 1416 | }, |
| 1388 | } | 1417 | } |
| | 1418 | } |
| | 1419 | |
| | 1420 | fn airStore(self: *Self, inst: Air.Inst.Index) !void { |
| | 1421 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| | 1422 | const ptr = try self.resolveInst(bin_op.lhs); |
| | 1423 | const value = try self.resolveInst(bin_op.rhs); |
| | 1424 | const ptr_ty = self.air.typeOf(bin_op.lhs); |
| | 1425 | const value_ty = self.air.typeOf(bin_op.rhs); |
| | 1426 | |
| | 1427 | try self.store(ptr, value, ptr_ty, value_ty); |
| | 1428 | |
| 1389 | return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); | 1429 | return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1390 | } | 1430 | } |
| 1391 | | 1431 | |