authorgravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-06-16 23:53:22+07:00
committergravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-06-24 21:19:33+07:00
log4d15284c3cbeefa771baa2b69866b2f0252f147b
treee7525ac6b6ee1e4a494c17159206dcce9ed64867
parent513ab4eb568da6fb926dd33ae067d31cf4831e79

stage2: sparc64: Implement SPARCv9 shifts


4 files changed, 86 insertions(+), 14 deletions(-)

src/arch/sparc64/CodeGen.zig-7
...@@ -2337,7 +2337,6 @@ fn binOpImmediate(...@@ -2337,7 +2337,6 @@ fn binOpImmediate(
2337 .sllx => .{2337 .sllx => .{
2338 .shift = .{2338 .shift = .{
2339 .is_imm = true,2339 .is_imm = true,
2340 .width = ShiftWidth.shift64,
2341 .rd = dest_reg,2340 .rd = dest_reg,
2342 .rs1 = lhs_reg,2341 .rs1 = lhs_reg,
2343 .rs2_or_imm = .{ .imm = @intCast(u6, rhs.immediate) },2342 .rs2_or_imm = .{ .imm = @intCast(u6, rhs.immediate) },
...@@ -2459,7 +2458,6 @@ fn binOpRegister(...@@ -2459,7 +2458,6 @@ fn binOpRegister(
2459 .sllx => .{2458 .sllx => .{
2460 .shift = .{2459 .shift = .{
2461 .is_imm = false,2460 .is_imm = false,
2462 .width = ShiftWidth.shift64,
2463 .rd = dest_reg,2461 .rd = dest_reg,
2464 .rs1 = lhs_reg,2462 .rs1 = lhs_reg,
2465 .rs2_or_imm = .{ .rs2 = rhs_reg },2463 .rs2_or_imm = .{ .rs2 = rhs_reg },
...@@ -2940,7 +2938,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -2940,7 +2938,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
2940 .data = .{2938 .data = .{
2941 .shift = .{2939 .shift = .{
2942 .is_imm = true,2940 .is_imm = true,
2943 .width = .shift64,
2944 .rd = reg,2941 .rd = reg,
2945 .rs1 = reg,2942 .rs1 = reg,
2946 .rs2_or_imm = .{ .imm = 12 },2943 .rs2_or_imm = .{ .imm = 12 },
...@@ -2971,7 +2968,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -2971,7 +2968,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
2971 .data = .{2968 .data = .{
2972 .shift = .{2969 .shift = .{
2973 .is_imm = true,2970 .is_imm = true,
2974 .width = .shift64,
2975 .rd = reg,2971 .rd = reg,
2976 .rs1 = reg,2972 .rs1 = reg,
2977 .rs2_or_imm = .{ .imm = 32 },2973 .rs2_or_imm = .{ .imm = 32 },
...@@ -3768,7 +3764,6 @@ fn truncRegister(...@@ -3768,7 +3764,6 @@ fn truncRegister(
3768 .data = .{3764 .data = .{
3769 .shift = .{3765 .shift = .{
3770 .is_imm = true,3766 .is_imm = true,
3771 .width = ShiftWidth.shift64,
3772 .rd = dest_reg,3767 .rd = dest_reg,
3773 .rs1 = operand_reg,3768 .rs1 = operand_reg,
3774 .rs2_or_imm = .{ .imm = @intCast(u6, 64 - int_bits) },3769 .rs2_or_imm = .{ .imm = @intCast(u6, 64 - int_bits) },
...@@ -3783,7 +3778,6 @@ fn truncRegister(...@@ -3783,7 +3778,6 @@ fn truncRegister(
3783 .data = .{3778 .data = .{
3784 .shift = .{3779 .shift = .{
3785 .is_imm = true,3780 .is_imm = true,
3786 .width = ShiftWidth.shift32,
3787 .rd = dest_reg,3781 .rd = dest_reg,
3788 .rs1 = dest_reg,3782 .rs1 = dest_reg,
3789 .rs2_or_imm = .{ .imm = @intCast(u6, int_bits) },3783 .rs2_or_imm = .{ .imm = @intCast(u6, int_bits) },
...@@ -3800,7 +3794,6 @@ fn truncRegister(...@@ -3800,7 +3794,6 @@ fn truncRegister(
3800 .data = .{3794 .data = .{
3801 .shift = .{3795 .shift = .{
3802 .is_imm = true,3796 .is_imm = true,
3803 .width = ShiftWidth.shift32,
3804 .rd = dest_reg,3797 .rd = dest_reg,
3805 .rs1 = operand_reg,3798 .rs1 = operand_reg,
3806 .rs2_or_imm = .{ .imm = 0 },3799 .rs2_or_imm = .{ .imm = 0 },
src/arch/sparc64/Emit.zig+38-6
...@@ -115,12 +115,12 @@ pub fn emitMir(...@@ -115,12 +115,12 @@ pub fn emitMir(
115115
116 .sethi => try emit.mirSethi(inst),116 .sethi => try emit.mirSethi(inst),
117117
118 .sll => @panic("TODO implement sparc64 sll"),118 .sll => try emit.mirShift(inst),
119 .srl => @panic("TODO implement sparc64 srl"),119 .srl => try emit.mirShift(inst),
120 .sra => @panic("TODO implement sparc64 sra"),120 .sra => try emit.mirShift(inst),
121 .sllx => @panic("TODO implement sparc64 sllx"),121 .sllx => try emit.mirShift(inst),
122 .srlx => @panic("TODO implement sparc64 srlx"),122 .srlx => try emit.mirShift(inst),
123 .srax => @panic("TODO implement sparc64 srax"),123 .srax => try emit.mirShift(inst),
124124
125 .stb => try emit.mirArithmetic3Op(inst),125 .stb => try emit.mirArithmetic3Op(inst),
126 .sth => try emit.mirArithmetic3Op(inst),126 .sth => try emit.mirArithmetic3Op(inst),
...@@ -370,6 +370,38 @@ fn mirSethi(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -370,6 +370,38 @@ fn mirSethi(emit: *Emit, inst: Mir.Inst.Index) !void {
370 try emit.writeInstruction(Instruction.sethi(imm, rd));370 try emit.writeInstruction(Instruction.sethi(imm, rd));
371}371}
372372
373fn mirShift(emit: *Emit, inst: Mir.Inst.Index) !void {
374 const tag = emit.mir.instructions.items(.tag)[inst];
375 const data = emit.mir.instructions.items(.data)[inst].shift;
376
377 const rd = data.rd;
378 const rs1 = data.rs1;
379
380 if (data.is_imm) {
381 const imm = data.rs2_or_imm.imm;
382 switch (tag) {
383 .sll => try emit.writeInstruction(Instruction.sll(u5, rs1, @truncate(u5, imm), rd)),
384 .srl => try emit.writeInstruction(Instruction.srl(u5, rs1, @truncate(u5, imm), rd)),
385 .sra => try emit.writeInstruction(Instruction.sra(u5, rs1, @truncate(u5, imm), rd)),
386 .sllx => try emit.writeInstruction(Instruction.sllx(u6, rs1, imm, rd)),
387 .srlx => try emit.writeInstruction(Instruction.srlx(u6, rs1, imm, rd)),
388 .srax => try emit.writeInstruction(Instruction.srax(u6, rs1, imm, rd)),
389 else => unreachable,
390 }
391 } else {
392 const rs2 = data.rs2_or_imm.rs2;
393 switch (tag) {
394 .sll => try emit.writeInstruction(Instruction.sll(Register, rs1, rs2, rd)),
395 .srl => try emit.writeInstruction(Instruction.srl(Register, rs1, rs2, rd)),
396 .sra => try emit.writeInstruction(Instruction.sra(Register, rs1, rs2, rd)),
397 .sllx => try emit.writeInstruction(Instruction.sllx(Register, rs1, rs2, rd)),
398 .srlx => try emit.writeInstruction(Instruction.srlx(Register, rs1, rs2, rd)),
399 .srax => try emit.writeInstruction(Instruction.srax(Register, rs1, rs2, rd)),
400 else => unreachable,
401 }
402 }
403}
404
373fn mirTrap(emit: *Emit, inst: Mir.Inst.Index) !void {405fn mirTrap(emit: *Emit, inst: Mir.Inst.Index) !void {
374 const tag = emit.mir.instructions.items(.tag)[inst];406 const tag = emit.mir.instructions.items(.tag)[inst];
375 const data = emit.mir.instructions.items(.data)[inst].trap;407 const data = emit.mir.instructions.items(.data)[inst].trap;
src/arch/sparc64/Mir.zig-1
...@@ -299,7 +299,6 @@ pub const Inst = struct {...@@ -299,7 +299,6 @@ pub const Inst = struct {
299 /// Used by e.g. sllx299 /// Used by e.g. sllx
300 shift: struct {300 shift: struct {
301 is_imm: bool,301 is_imm: bool,
302 width: Instruction.ShiftWidth,
303 rd: Register,302 rd: Register,
304 rs1: Register,303 rs1: Register,
305 rs2_or_imm: union {304 rs2_or_imm: union {
src/arch/sparc64/bits.zig+48
...@@ -1313,6 +1313,54 @@ pub const Instruction = union(enum) {...@@ -1313,6 +1313,54 @@ pub const Instruction = union(enum) {
1313 return format2a(0b100, imm, rd);1313 return format2a(0b100, imm, rd);
1314 }1314 }
13151315
1316 pub fn sll(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
1317 return switch (s2) {
1318 Register => format3k(0b11, 0b10_0101, .shift32, rs1, rs2, rd),
1319 u5 => format3l(0b11, 0b10_0101, rs1, rs2, rd),
1320 else => unreachable,
1321 };
1322 }
1323
1324 pub fn srl(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
1325 return switch (s2) {
1326 Register => format3k(0b11, 0b10_0110, .shift32, rs1, rs2, rd),
1327 u5 => format3l(0b11, 0b10_0110, rs1, rs2, rd),
1328 else => unreachable,
1329 };
1330 }
1331
1332 pub fn sra(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
1333 return switch (s2) {
1334 Register => format3k(0b11, 0b10_0111, .shift32, rs1, rs2, rd),
1335 u5 => format3l(0b11, 0b10_0111, rs1, rs2, rd),
1336 else => unreachable,
1337 };
1338 }
1339
1340 pub fn sllx(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
1341 return switch (s2) {
1342 Register => format3k(0b11, 0b10_0101, .shift64, rs1, rs2, rd),
1343 u6 => format3m(0b11, 0b10_0101, rs1, rs2, rd),
1344 else => unreachable,
1345 };
1346 }
1347
1348 pub fn srlx(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
1349 return switch (s2) {
1350 Register => format3k(0b11, 0b10_0110, .shift64, rs1, rs2, rd),
1351 u6 => format3m(0b11, 0b10_0110, rs1, rs2, rd),
1352 else => unreachable,
1353 };
1354 }
1355
1356 pub fn srax(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
1357 return switch (s2) {
1358 Register => format3k(0b11, 0b10_0111, .shift64, rs1, rs2, rd),
1359 u6 => format3m(0b11, 0b10_0111, rs1, rs2, rd),
1360 else => unreachable,
1361 };
1362 }
1363
1316 pub fn stb(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {1364 pub fn stb(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
1317 return switch (s2) {1365 return switch (s2) {
1318 Register => format3a(0b11, 0b00_0101, rs1, rs2, rd),1366 Register => format3a(0b11, 0b00_0101, rs1, rs2, rd),