From 672da9c613939c5c76e68cb3acae9f65845f6e56 Mon Sep 17 00:00:00 2001 From: Koakuma Date: Sun, 13 Mar 2022 22:29:50 +0700 Subject: [PATCH] stage2 sparcv9: Add CCR and RCondition enums This adds the list of CCRs and `rcond` constants as specified by the ISA, and changes the template functions to use them. --- src/arch/sparcv9/bits.zig | 54 +++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/src/arch/sparcv9/bits.zig b/src/arch/sparcv9/bits.zig index a1e9973f91..e96a4555eb 100644 --- a/src/arch/sparcv9/bits.zig +++ b/src/arch/sparcv9/bits.zig @@ -446,6 +446,32 @@ pub const Instruction = union(enum) { rs2: u5, }, + pub const CCR = enum(u3) { + fcc0, + fcc1, + fcc2, + fcc3, + icc, + reserved1, + xcc, + reserved2, + }; + + pub const RCondition = enum(u3) { + reserved1, + eq_zero, + le_zero, + lt_zero, + reserved, + ne_zero, + gt_zero, + ge_zero, + }; + + // TODO: Need to define an enum for `cond` values + // This is kinda challenging since the cond values have different meanings + // depending on whether it's operating on integer or FP CCR. + pub fn toU32(self: Instruction) u32 { return @bitCast(u32, self); } @@ -462,17 +488,16 @@ pub const Instruction = union(enum) { } fn format2a(rd: Register, op2: u3, imm: i22) Instruction { - const umm = @bitCast(u22, imm); return Instruction{ .format_2a = .{ .rd = rd.enc(), .op2 = op2, - .imm22 = umm, + .imm22 = @bitCast(u22, imm), }, }; } - fn format2b(a: u1, cond: u4, op2: u3, disp: i24) Instruction { + fn format2b(annul: bool, cond: u4, op2: u3, disp: i24) Instruction { // In SPARC, branch target needs to be aligned to 4 bytes. assert(disp % 4 == 0); @@ -480,7 +505,7 @@ pub const Instruction = union(enum) { const udisp = @truncate(u22, @bitCast(u24, disp) >> 2); return Instruction{ .format_2b = .{ - .a = a, + .a = @boolToInt(annul), .cond = cond, .op2 = op2, .disp22 = udisp, @@ -488,26 +513,29 @@ pub const Instruction = union(enum) { }; } - fn format2c(a: u1, cond: u4, op2: u3, cc1: u1, cc0: u1, p: u1, disp: i21) Instruction { + fn format2c(annul: bool, cond: u4, op2: u3, ccr: CCR, pt: bool, disp: i21) Instruction { // In SPARC, branch target needs to be aligned to 4 bytes. assert(disp % 4 == 0); // Discard the last two bits since those are implicitly zero. const udisp = @truncate(u19, @bitCast(u21, disp) >> 2); + + const ccr_cc1 = @truncate(u1, @enumToInt(ccr) > 1); + const ccr_cc0 = @truncate(u1, @enumToInt(ccr)); return Instruction{ .format_2c = .{ - .a = a, + .a = @boolToInt(annul), .cond = cond, .op2 = op2, - .cc1 = cc1, - .cc0 = cc0, - .p = p, + .cc1 = ccr_cc1, + .cc0 = ccr_cc0, + .p = @boolToInt(pt), .disp19 = udisp, }, }; } - fn format2d(a: u1, rcond: u3, op2: u3, p: u1, rs1: Register, disp: i18) Instruction { + fn format2d(annul: bool, rcond: RCondition, op2: u3, pt: bool, rs1: Register, disp: i18) Instruction { // In SPARC, branch target needs to be aligned to 4 bytes. assert(disp % 4 == 0); @@ -518,10 +546,10 @@ pub const Instruction = union(enum) { const udisp_lo = @truncate(u14, udisp & 0b0011_1111_1111_1111); return Instruction{ .format_2a = .{ - .a = a, - .rcond = rcond, + .a = @boolToInt(annul), + .rcond = @enumToInt(rcond), .op2 = op2, - .p = p, + .p = @boolToInt(pt), .rs1 = rs1.enc(), .d16hi = udisp_hi, .d16lo = udisp_lo,