Skip to content

Commit 8dd9173

Browse files
committed
feat(jit): emit unsigned 64-bit arithmetic (#56)
1 parent b21cdfb commit 8dd9173

1 file changed

Lines changed: 49 additions & 0 deletions

File tree

‎src/jit/aarch64.zig‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,14 @@ pub const Assembler = struct {
7373
try self.emit32(0x8b00_0000 | (@as(u32, rm) << 16) | (@as(u32, rn) << 5) | rd);
7474
}
7575

76+
pub fn subtractRegister64(self: *Assembler, rd: u5, rn: u5, rm: u5) error{NoSpace}!void {
77+
try self.emit32(0xcb00_0000 | (@as(u32, rm) << 16) | (@as(u32, rn) << 5) | rd);
78+
}
79+
80+
pub fn multiply64(self: *Assembler, rd: u5, rn: u5, rm: u5) error{NoSpace}!void {
81+
try self.emit32(0x9b00_7c00 | (@as(u32, rm) << 16) | (@as(u32, rn) << 5) | rd);
82+
}
83+
7684
pub fn subtractImmediate64(self: *Assembler, rd: u5, rn: u5, value: u12) error{NoSpace}!void {
7785
try self.emit32(0xd100_0000 | (@as(u32, value) << 10) | (@as(u32, rn) << 5) | rd);
7886
}
@@ -155,14 +163,30 @@ pub const Assembler = struct {
155163
try self.emit32(0x1e63_0000 | (@as(u32, rn) << 5) | fd);
156164
}
157165

166+
pub fn convertFloat64ToUnsigned64(self: *Assembler, rd: u5, fn_: u5) error{NoSpace}!void {
167+
try self.emit32(0x9e79_0000 | (@as(u32, fn_) << 5) | rd);
168+
}
169+
170+
pub fn convertUnsigned64ToFloat64(self: *Assembler, fd: u5, rn: u5) error{NoSpace}!void {
171+
try self.emit32(0x9e63_0000 | (@as(u32, rn) << 5) | fd);
172+
}
173+
158174
pub fn divideUnsigned32(self: *Assembler, rd: u5, rn: u5, rm: u5) error{NoSpace}!void {
159175
try self.emit32(0x1ac0_0800 | (@as(u32, rm) << 16) | (@as(u32, rn) << 5) | rd);
160176
}
161177

178+
pub fn divideUnsigned64(self: *Assembler, rd: u5, rn: u5, rm: u5) error{NoSpace}!void {
179+
try self.emit32(0x9ac0_0800 | (@as(u32, rm) << 16) | (@as(u32, rn) << 5) | rd);
180+
}
181+
162182
pub fn multiplySubtract32(self: *Assembler, rd: u5, rn: u5, rm: u5, ra: u5) error{NoSpace}!void {
163183
try self.emit32(0x1b00_8000 | (@as(u32, rm) << 16) | (@as(u32, ra) << 10) | (@as(u32, rn) << 5) | rd);
164184
}
165185

186+
pub fn multiplySubtract64(self: *Assembler, rd: u5, rn: u5, rm: u5, ra: u5) error{NoSpace}!void {
187+
try self.emit32(0x9b00_8000 | (@as(u32, rm) << 16) | (@as(u32, ra) << 10) | (@as(u32, rn) << 5) | rd);
188+
}
189+
166190
pub fn conditionalSet32(self: *Assembler, rd: u5, condition: Condition) error{NoSpace}!void {
167191
try self.emit32(0x1a9f_07e0 | (@as(u32, @intFromEnum(condition.inverted())) << 12) | rd);
168192
}
@@ -361,6 +385,31 @@ test "AArch64 guarded unsigned remainder encodings" {
361385
}
362386
}
363387

388+
test "AArch64 guarded unsigned 64-bit arithmetic encodings" {
389+
var storage: [28]u8 = undefined;
390+
var assembler = Assembler.init(&storage);
391+
try assembler.subtractRegister64(9, 10, 11);
392+
try assembler.multiply64(12, 13, 14);
393+
try assembler.divideUnsigned64(15, 16, 17);
394+
try assembler.multiplySubtract64(18, 19, 20, 21);
395+
try assembler.convertUnsigned64ToFloat64(2, 22);
396+
try assembler.convertFloat64ToUnsigned64(23, 3);
397+
try assembler.ret();
398+
399+
const expected = [_]u32{
400+
0xcb0b_0149,
401+
0x9b0e_7dac,
402+
0x9ad1_0a0f,
403+
0x9b14_d672,
404+
0x9e63_02c2,
405+
0x9e79_0077,
406+
0xd65f_03c0,
407+
};
408+
for (expected, 0..) |instruction, index| {
409+
try std.testing.expectEqual(instruction, std.mem.readInt(u32, assembler.bytes()[index * 4 ..][0..4], .little));
410+
}
411+
}
412+
364413
test "AArch64 preserves register-resident numeric stack" {
365414
var storage: [24]u8 = undefined;
366415
var assembler = Assembler.init(&storage);

0 commit comments

Comments
 (0)