Commit 672da9c613

Koakuma <koachan@protonmail.com>
2022-03-13 16:29:50
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.
1 parent fbcea86
Changed files (1)
src
arch
sparcv9
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,