authorgravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-03-13 22:29:50+07:00
committergravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-03-16 21:38:42+07:00
log672da9c613939c5c76e68cb3acae9f65845f6e56
tree43f251583b48fa20f797cddfb8c08dd9f6951193
parentfbcea863334bebdd6bb465c84b97122e78f19d5d

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 files changed, 41 insertions(+), 13 deletions(-)

src/arch/sparcv9/bits.zig+41-13
...@@ -446,6 +446,32 @@ pub const Instruction = union(enum) {...@@ -446,6 +446,32 @@ pub const Instruction = union(enum) {
446 rs2: u5,446 rs2: u5,
447 },447 },
448448
449 pub const CCR = enum(u3) {
450 fcc0,
451 fcc1,
452 fcc2,
453 fcc3,
454 icc,
455 reserved1,
456 xcc,
457 reserved2,
458 };
459
460 pub const RCondition = enum(u3) {
461 reserved1,
462 eq_zero,
463 le_zero,
464 lt_zero,
465 reserved,
466 ne_zero,
467 gt_zero,
468 ge_zero,
469 };
470
471 // TODO: Need to define an enum for `cond` values
472 // This is kinda challenging since the cond values have different meanings
473 // depending on whether it's operating on integer or FP CCR.
474
449 pub fn toU32(self: Instruction) u32 {475 pub fn toU32(self: Instruction) u32 {
450 return @bitCast(u32, self);476 return @bitCast(u32, self);
451 }477 }
...@@ -462,17 +488,16 @@ pub const Instruction = union(enum) {...@@ -462,17 +488,16 @@ pub const Instruction = union(enum) {
462 }488 }
463489
464 fn format2a(rd: Register, op2: u3, imm: i22) Instruction {490 fn format2a(rd: Register, op2: u3, imm: i22) Instruction {
465 const umm = @bitCast(u22, imm);
466 return Instruction{491 return Instruction{
467 .format_2a = .{492 .format_2a = .{
468 .rd = rd.enc(),493 .rd = rd.enc(),
469 .op2 = op2,494 .op2 = op2,
470 .imm22 = umm,495 .imm22 = @bitCast(u22, imm),
471 },496 },
472 };497 };
473 }498 }
474499
475 fn format2b(a: u1, cond: u4, op2: u3, disp: i24) Instruction {500 fn format2b(annul: bool, cond: u4, op2: u3, disp: i24) Instruction {
476 // In SPARC, branch target needs to be aligned to 4 bytes.501 // In SPARC, branch target needs to be aligned to 4 bytes.
477 assert(disp % 4 == 0);502 assert(disp % 4 == 0);
478503
...@@ -480,7 +505,7 @@ pub const Instruction = union(enum) {...@@ -480,7 +505,7 @@ pub const Instruction = union(enum) {
480 const udisp = @truncate(u22, @bitCast(u24, disp) >> 2);505 const udisp = @truncate(u22, @bitCast(u24, disp) >> 2);
481 return Instruction{506 return Instruction{
482 .format_2b = .{507 .format_2b = .{
483 .a = a,508 .a = @boolToInt(annul),
484 .cond = cond,509 .cond = cond,
485 .op2 = op2,510 .op2 = op2,
486 .disp22 = udisp,511 .disp22 = udisp,
...@@ -488,26 +513,29 @@ pub const Instruction = union(enum) {...@@ -488,26 +513,29 @@ pub const Instruction = union(enum) {
488 };513 };
489 }514 }
490515
491 fn format2c(a: u1, cond: u4, op2: u3, cc1: u1, cc0: u1, p: u1, disp: i21) Instruction {516 fn format2c(annul: bool, cond: u4, op2: u3, ccr: CCR, pt: bool, disp: i21) Instruction {
492 // In SPARC, branch target needs to be aligned to 4 bytes.517 // In SPARC, branch target needs to be aligned to 4 bytes.
493 assert(disp % 4 == 0);518 assert(disp % 4 == 0);
494519
495 // Discard the last two bits since those are implicitly zero.520 // Discard the last two bits since those are implicitly zero.
496 const udisp = @truncate(u19, @bitCast(u21, disp) >> 2);521 const udisp = @truncate(u19, @bitCast(u21, disp) >> 2);
522
523 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) > 1);
524 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));
497 return Instruction{525 return Instruction{
498 .format_2c = .{526 .format_2c = .{
499 .a = a,527 .a = @boolToInt(annul),
500 .cond = cond,528 .cond = cond,
501 .op2 = op2,529 .op2 = op2,
502 .cc1 = cc1,530 .cc1 = ccr_cc1,
503 .cc0 = cc0,531 .cc0 = ccr_cc0,
504 .p = p,532 .p = @boolToInt(pt),
505 .disp19 = udisp,533 .disp19 = udisp,
506 },534 },
507 };535 };
508 }536 }
509537
510 fn format2d(a: u1, rcond: u3, op2: u3, p: u1, rs1: Register, disp: i18) Instruction {538 fn format2d(annul: bool, rcond: RCondition, op2: u3, pt: bool, rs1: Register, disp: i18) Instruction {
511 // In SPARC, branch target needs to be aligned to 4 bytes.539 // In SPARC, branch target needs to be aligned to 4 bytes.
512 assert(disp % 4 == 0);540 assert(disp % 4 == 0);
513541
...@@ -518,10 +546,10 @@ pub const Instruction = union(enum) {...@@ -518,10 +546,10 @@ pub const Instruction = union(enum) {
518 const udisp_lo = @truncate(u14, udisp & 0b0011_1111_1111_1111);546 const udisp_lo = @truncate(u14, udisp & 0b0011_1111_1111_1111);
519 return Instruction{547 return Instruction{
520 .format_2a = .{548 .format_2a = .{
521 .a = a,549 .a = @boolToInt(annul),
522 .rcond = rcond,550 .rcond = @enumToInt(rcond),
523 .op2 = op2,551 .op2 = op2,
524 .p = p,552 .p = @boolToInt(pt),
525 .rs1 = rs1.enc(),553 .rs1 = rs1.enc(),
526 .d16hi = udisp_hi,554 .d16hi = udisp_hi,
527 .d16lo = udisp_lo,555 .d16lo = udisp_lo,