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(
23372337 .sllx => .{
23382338 .shift = .{
23392339 .is_imm = true,
2340 .width = ShiftWidth.shift64,
23412340 .rd = dest_reg,
23422341 .rs1 = lhs_reg,
23432342 .rs2_or_imm = .{ .imm = @intCast(u6, rhs.immediate) },
......@@ -2459,7 +2458,6 @@ fn binOpRegister(
24592458 .sllx => .{
24602459 .shift = .{
24612460 .is_imm = false,
2462 .width = ShiftWidth.shift64,
24632461 .rd = dest_reg,
24642462 .rs1 = lhs_reg,
24652463 .rs2_or_imm = .{ .rs2 = rhs_reg },
......@@ -2940,7 +2938,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
29402938 .data = .{
29412939 .shift = .{
29422940 .is_imm = true,
2943 .width = .shift64,
29442941 .rd = reg,
29452942 .rs1 = reg,
29462943 .rs2_or_imm = .{ .imm = 12 },
......@@ -2971,7 +2968,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
29712968 .data = .{
29722969 .shift = .{
29732970 .is_imm = true,
2974 .width = .shift64,
29752971 .rd = reg,
29762972 .rs1 = reg,
29772973 .rs2_or_imm = .{ .imm = 32 },
......@@ -3768,7 +3764,6 @@ fn truncRegister(
37683764 .data = .{
37693765 .shift = .{
37703766 .is_imm = true,
3771 .width = ShiftWidth.shift64,
37723767 .rd = dest_reg,
37733768 .rs1 = operand_reg,
37743769 .rs2_or_imm = .{ .imm = @intCast(u6, 64 - int_bits) },
......@@ -3783,7 +3778,6 @@ fn truncRegister(
37833778 .data = .{
37843779 .shift = .{
37853780 .is_imm = true,
3786 .width = ShiftWidth.shift32,
37873781 .rd = dest_reg,
37883782 .rs1 = dest_reg,
37893783 .rs2_or_imm = .{ .imm = @intCast(u6, int_bits) },
......@@ -3800,7 +3794,6 @@ fn truncRegister(
38003794 .data = .{
38013795 .shift = .{
38023796 .is_imm = true,
3803 .width = ShiftWidth.shift32,
38043797 .rd = dest_reg,
38053798 .rs1 = operand_reg,
38063799 .rs2_or_imm = .{ .imm = 0 },
src/arch/sparc64/Emit.zig+38-6
......@@ -115,12 +115,12 @@ pub fn emitMir(
115115
116116 .sethi => try emit.mirSethi(inst),
117117
118 .sll => @panic("TODO implement sparc64 sll"),
119 .srl => @panic("TODO implement sparc64 srl"),
120 .sra => @panic("TODO implement sparc64 sra"),
121 .sllx => @panic("TODO implement sparc64 sllx"),
122 .srlx => @panic("TODO implement sparc64 srlx"),
123 .srax => @panic("TODO implement sparc64 srax"),
118 .sll => try emit.mirShift(inst),
119 .srl => try emit.mirShift(inst),
120 .sra => try emit.mirShift(inst),
121 .sllx => try emit.mirShift(inst),
122 .srlx => try emit.mirShift(inst),
123 .srax => try emit.mirShift(inst),
124124
125125 .stb => try emit.mirArithmetic3Op(inst),
126126 .sth => try emit.mirArithmetic3Op(inst),
......@@ -370,6 +370,38 @@ fn mirSethi(emit: *Emit, inst: Mir.Inst.Index) !void {
370370 try emit.writeInstruction(Instruction.sethi(imm, rd));
371371}
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
373405fn mirTrap(emit: *Emit, inst: Mir.Inst.Index) !void {
374406 const tag = emit.mir.instructions.items(.tag)[inst];
375407 const data = emit.mir.instructions.items(.data)[inst].trap;
src/arch/sparc64/Mir.zig-1
......@@ -299,7 +299,6 @@ pub const Inst = struct {
299299 /// Used by e.g. sllx
300300 shift: struct {
301301 is_imm: bool,
302 width: Instruction.ShiftWidth,
303302 rd: Register,
304303 rs1: Register,
305304 rs2_or_imm: union {
src/arch/sparc64/bits.zig+48
......@@ -1313,6 +1313,54 @@ pub const Instruction = union(enum) {
13131313 return format2a(0b100, imm, rd);
13141314 }
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
13161364 pub fn stb(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
13171365 return switch (s2) {
13181366 Register => format3a(0b11, 0b00_0101, rs1, rs2, rd),