authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-10-23 20:33:46+02:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-11-01 20:43:27+01:00
log4e0779813b5a25755f6a5f12e8ec05304abb2337
tree3da90aacbeac369f3b7ee4a4f01d18d87c80feae
parent8a022d9c92e2a21b3329da1b01151d2b14f0b1da
signature Commit is signed but in an unrecognized format.

stage2 AArch64: add inline memset


1 files changed, 103 insertions(+), 1 deletions(-)

src/arch/aarch64/CodeGen.zig+103-1
......@@ -3459,6 +3459,104 @@ fn genInlineMemcpy(
34593459 // end:
34603460}
34613461
3462fn genInlineMemset(
3463 self: *Self,
3464 dst: MCValue,
3465 val: MCValue,
3466 len: MCValue,
3467) !void {
3468 const dst_reg = switch (dst) {
3469 .register => |r| r,
3470 else => try self.copyToTmpRegister(Type.initTag(.manyptr_u8), dst),
3471 };
3472 const dst_reg_lock = self.register_manager.lockReg(dst_reg);
3473 defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock);
3474
3475 const val_reg = switch (val) {
3476 .register => |r| r,
3477 else => try self.copyToTmpRegister(Type.initTag(.u8), val),
3478 };
3479 const val_reg_lock = self.register_manager.lockReg(val_reg);
3480 defer if (val_reg_lock) |lock| self.register_manager.unlockReg(lock);
3481
3482 const len_reg = switch (len) {
3483 .register => |r| r,
3484 else => try self.copyToTmpRegister(Type.usize, len),
3485 };
3486 const len_reg_lock = self.register_manager.lockReg(len_reg);
3487 defer if (len_reg_lock) |lock| self.register_manager.unlockReg(lock);
3488
3489 const count_reg = try self.register_manager.allocReg(null, gp);
3490
3491 try self.genInlineMemsetCode(dst_reg, val_reg, len_reg, count_reg);
3492}
3493
3494fn genInlineMemsetCode(
3495 self: *Self,
3496 dst: Register,
3497 val: Register,
3498 len: Register,
3499 count: Register,
3500) !void {
3501 // mov count, #0
3502 _ = try self.addInst(.{
3503 .tag = .movz,
3504 .data = .{ .r_imm16_sh = .{
3505 .rd = count,
3506 .imm16 = 0,
3507 } },
3508 });
3509
3510 // loop:
3511 // cmp count, len
3512 _ = try self.addInst(.{
3513 .tag = .cmp_shifted_register,
3514 .data = .{ .rr_imm6_shift = .{
3515 .rn = count,
3516 .rm = len,
3517 .imm6 = 0,
3518 .shift = .lsl,
3519 } },
3520 });
3521
3522 // bge end
3523 _ = try self.addInst(.{
3524 .tag = .b_cond,
3525 .data = .{ .inst_cond = .{
3526 .inst = @intCast(u32, self.mir_instructions.len + 4),
3527 .cond = .ge,
3528 } },
3529 });
3530
3531 // strb val, [src, count]
3532 _ = try self.addInst(.{
3533 .tag = .strb_register,
3534 .data = .{ .load_store_register_register = .{
3535 .rt = val,
3536 .rn = dst,
3537 .offset = Instruction.LoadStoreOffset.reg(count).register,
3538 } },
3539 });
3540
3541 // add count, count, #1
3542 _ = try self.addInst(.{
3543 .tag = .add_immediate,
3544 .data = .{ .rr_imm12_sh = .{
3545 .rd = count,
3546 .rn = count,
3547 .imm12 = 1,
3548 } },
3549 });
3550
3551 // b loop
3552 _ = try self.addInst(.{
3553 .tag = .b,
3554 .data = .{ .inst = @intCast(u32, self.mir_instructions.len - 4) },
3555 });
3556
3557 // end:
3558}
3559
34623560fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
34633561 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
34643562 const elem_ty = self.air.typeOfIndex(inst);
......@@ -4910,7 +5008,11 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
49105008 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }),
49115009 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }),
49125010 8 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaaaaaaaaaa }),
4913 else => return self.fail("TODO implement memset", .{}),
5011 else => try self.genInlineMemset(
5012 .{ .ptr_stack_offset = stack_offset },
5013 .{ .immediate = 0xaa },
5014 .{ .immediate = abi_size },
5015 ),
49145016 }
49155017 },
49165018 .compare_flags,