| ... | ... | @@ -3459,6 +3459,104 @@ fn genInlineMemcpy( |
| 3459 | 3459 | // end: |
| 3460 | 3460 | } |
| 3461 | 3461 | |
| 3462 | fn 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 | |
| 3494 | fn 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 | |
| 3462 | 3560 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 3463 | 3561 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 3464 | 3562 | const elem_ty = self.air.typeOfIndex(inst); |
| ... | ... | @@ -4910,7 +5008,11 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 4910 | 5008 | 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }), |
| 4911 | 5009 | 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }), |
| 4912 | 5010 | 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 | ), |
| 4914 | 5016 | } |
| 4915 | 5017 | }, |
| 4916 | 5018 | .compare_flags, |