remove mask from mips and gte instruction encoders. missing math changes.

This commit is contained in:
ed
2026-08-13 23:39:35 -04:00
parent 9a6eca6047
commit d88e0d0487
3 changed files with 31 additions and 26 deletions
+13 -14
View File
@@ -177,18 +177,17 @@ enum {
* Mirrors the OPCODE_SHIFT / RS_SHIFT convention used in mips.h. * Mirrors the OPCODE_SHIFT / RS_SHIFT convention used in mips.h.
*/ */
gte_shift_sf = 19, gte_width_sf = 1, gte_mask_sf = 0x1, gte_shift_sf = 19, gte_width_sf = 1,
gte_shift_mx = 17, gte_width_mx = 2, gte_mask_mx = 0x3, gte_shift_mx = 17, gte_width_mx = 2,
gte_shift_v = 15, gte_width_v = 2, gte_mask_v = 0x3, gte_shift_v = 15, gte_width_v = 2,
gte_shift_cv = 13, gte_width_cv = 2, gte_mask_cv = 0x3, gte_shift_cv = 13, gte_width_cv = 2,
gte_shift_lm = 10, gte_width_lm = 1, gte_mask_lm = 0x1, gte_shift_lm = 10, gte_width_lm = 1,
gte_shift_cmd = 0, gte_width_cmd = 6, gte_mask_cmd = 0x3F, gte_shift_cmd = 0, gte_width_cmd = 6,
/* Fake command number (bits 24-20) — IGNORED by the GTE hardware per PSX-SPX `geometrytransformationenginegte.md` line 48. /* Fake command number (bits 24-20) — IGNORED by the GTE hardware per PSX-SPX `geometrytransformationenginegte.md` line 48.
* libgte's compiler emits non-zero values in this field as a disassembly signature. */ * libgte's compiler emits non-zero values in this field as a disassembly signature. */
gte_shift_fake_cmd = 20, gte_shift_fake_cmd = 20,
gte_width_fake_cmd = 5, gte_width_fake_cmd = 5,
gte_mask_fake_cmd = 0x1F,
}; };
/* --- GTE Control Register Aliases (Pitfall 1) --- /* --- GTE Control Register Aliases (Pitfall 1) ---
@@ -351,13 +350,13 @@ enum { _C2_TX_SUBS_ = 0
#define gte_cmd_base (enc_op(op_cop2) | (1 << 25)) #define gte_cmd_base (enc_op(op_cop2) | (1 << 25))
/* Per-field encoders. Each one does (value & mask) << shift on its own. */ /* Per-field encoders. Each one does (value & mask) << shift on its own. */
#define enc_gte_sf(sf) (((sf) & gte_mask_sf ) << gte_shift_sf ) #define enc_gte_sf(sf) ((sf) << gte_shift_sf )
#define enc_gte_mx(mx) (((mx) & gte_mask_mx ) << gte_shift_mx ) #define enc_gte_mx(mx) ((mx) << gte_shift_mx )
#define enc_gte_v(v) (((v) & gte_mask_v ) << gte_shift_v ) #define enc_gte_v(v) ((v) << gte_shift_v )
#define enc_gte_cv(cv) (((cv) & gte_mask_cv ) << gte_shift_cv ) #define enc_gte_cv(cv) ((cv) << gte_shift_cv )
#define enc_gte_lm(lm) (((lm) & gte_mask_lm ) << gte_shift_lm ) #define enc_gte_lm(lm) ((lm) << gte_shift_lm )
#define enc_gte_cmd(cmd) (((cmd) & gte_mask_cmd ) << gte_shift_cmd ) #define enc_gte_cmd(cmd) ((cmd) << gte_shift_cmd )
#define enc_gte_fake_cmd(x) (((x) & gte_mask_fake_cmd) << gte_shift_fake_cmd) #define enc_gte_fake_cmd(x) ((x) << gte_shift_fake_cmd)
/* Composite: all six GTE fields + the COP2/CO base. */ /* Composite: all six GTE fields + the COP2/CO base. */
#define enc_gte_cmdw(sf, mx, v, cv, lm, cmd) ( \ #define enc_gte_cmdw(sf, mx, v, cv, lm, cmd) ( \
+6
View File
@@ -24,6 +24,7 @@ enum {
}; };
typedef Array_(U1, 2); typedef Array_(U1, 2);
typedef Array_(U2, 2);
typedef Array_(U4, 2); typedef Array_(U4, 2);
typedef Array_(S2, 2); typedef Array_(S2, 2);
typedef Array_(S2, 3); typedef Array_(S2, 3);
@@ -46,6 +47,9 @@ typedef Struct_(V4_S4) { S4 x; S4 y; S4 z; S4 w; };
// typedef Struct_(P3_S4) { S4 x; S4 y; S4 z; S4 w1; }; // RGA(Lengyel): Affine point with implicit weight one. Storage alias of V3_S4. Use P3_S4 when the value is a point. // typedef Struct_(P3_S4) { S4 x; S4 y; S4 z; S4 w1; }; // RGA(Lengyel): Affine point with implicit weight one. Storage alias of V3_S4. Use P3_S4 when the value is a point.
typedef V3_S4 P3_S4; typedef V3_S4 P3_S4;
typedef Struct_(R1_U2) { U2 p0; U2 p1; };
typedef Struct_(R1_S2) { S2 p0; S2 p1; };
typedef Struct_(R2_S2) { V2_S2 p0; V2_S2 p1; }; // Range-2 Signed 2-Byte (16-bit) typedef Struct_(R2_S2) { V2_S2 p0; V2_S2 p1; }; // Range-2 Signed 2-Byte (16-bit)
typedef Struct_(R2_S4) { V2_S4 p0; V2_S4 p1; }; // Range-2 Signed 4-Byte (32-bit) typedef Struct_(R2_S4) { V2_S4 p0; V2_S4 p1; }; // Range-2 Signed 4-Byte (32-bit)
@@ -64,6 +68,8 @@ typedef Array_(V2_S2, 2);
typedef Array_(V2_S2, 3); typedef Array_(V2_S2, 3);
typedef Array_(V2_S2, 4); typedef Array_(V2_S2, 4);
#define r1u2(p0,p1) (R1_U2){p0,p1}
enum { enum {
fp_one = (1 << 12), fp_one = (1 << 12),
}; };
+12 -12
View File
@@ -259,22 +259,22 @@ enum { _BitOffsets = 0
, SHAMT_SHIFT = 6 /* Shift Amount */ , SHAMT_SHIFT = 6 /* Shift Amount */
, FC_SHIFT = 0 , FC_SHIFT = 0
/* Bit Masks to prevent overflow into adjacent fields */ /* IMM_MASK is the 16-bit two's-complement truncation for the immediate field.
* It is NOT a range guard — it is load-bearing for negative branch offsets
* (the metaprogram emits raw signed offsets; the mask truncates them to the
* 16-bit representation the hardware expects). The static analysis
* `immediate_field_width` check validates ranges at build time. */
, OPCODE_MASK = 0x3F
, REG_MASK = 0x1F
, SHAMT_MASK = 0x1F /* Shift Amount */
, FC_MASK = 0x3F
, IMM_MASK = 0xFFFF , IMM_MASK = 0xFFFF
}; };
#define enc_op(op) (((op) & OPCODE_MASK) << OPCODE_SHIFT) #define enc_op(op) ((op) << OPCODE_SHIFT)
#define enc_rs(rs) (((rs) & REG_MASK) << RS_SHIFT) #define enc_rs(rs) ((rs) << RS_SHIFT)
#define enc_rt(rt) (((rt) & REG_MASK) << RT_SHIFT) #define enc_rt(rt) ((rt) << RT_SHIFT)
#define enc_rd(rd) (((rd) & REG_MASK) << RD_SHIFT) #define enc_rd(rd) ((rd) << RD_SHIFT)
#define enc_shamt(shamt) (((shamt) & SHAMT_MASK) << SHAMT_SHIFT) #define enc_shamt(shamt) ((shamt) << SHAMT_SHIFT)
#define enc_fc(fc) (((fc) & FC_MASK) << FC_SHIFT) #define enc_fc(fc) ((fc) << FC_SHIFT)
#define enc_imm(imm) (((imm) & IMM_MASK)) #define enc_imm(imm) ((imm) & IMM_MASK)
/* MIPS R-Type Instruction Format (Register-to-Register) */ /* MIPS R-Type Instruction Format (Register-to-Register) */
#define enc_r(op, rs, rt, rd, shamt, fc) (enc_op(op) | enc_rs(rs) | enc_rt(rt) | enc_rd(rd) | enc_shamt(shamt) | enc_fc(fc)) #define enc_r(op, rs, rt, rd, shamt, fc) (enc_op(op) | enc_rs(rs) | enc_rt(rt) | enc_rd(rd) | enc_shamt(shamt) | enc_fc(fc))