79607371

Date: 2025-05-05 17:24:29
Score: 1.5
Natty:
Report link

Based on the answer of @chqrlie I ended up with following simplification that basically solves what I wanted to solve:

if (!Is_sup_sz(SZ_L(d))) { return EXEC_ERROR_INVALID_OP_SZ; }
switch (LAYOUT(d)) {
    case Ops_layout_Reg2:
        Reg_set(&REG_L(s,d), &REG_R(s,d), SZ_L(d));
        break;
    case Ops_layout_RegImm:
        Reg_set(&REG_L(s,d), &IMM1(d), SZ_L(d));
        break;
    case Ops_layout_Imm2:
    case Ops_layout_ImmReg:
    default: return EXEC_ERROR_INVALID_3ADDR_OPS_LAYOUT;
}
return EXEC_CORRECT;

where 2 additional functions resolve what part of Cell16 (renamed to just Cell) is to be modified and what operand size is correct to be processed using compile time constant:

#define SUP_SZ_MASK (uint8_t)0x18 // 0b00011000 only 8/16 bit.
inline bool Is_sup_sz(Op_sz sz) {
    return (sz != 0) && ((sz & (sz - 1)) == 0) && ((sz & SUP_SZ_MASK) != 0);
}
inline void Reg_set(Cell *dest, const Cell *src, Op_sz sz) {
    // Formula guarantees no overflow even for uint64_t.
    uint16_t mask_right  = (((1 << (sz - 1)) - 1) << 1) + 1, 
             mask_left = ~mask_right;
    // Only work with widest value of Cell.
    dest->sz16 &= mask_left;
    dest->sz16 |= (src->sz16 & mask_right);
}

I decided to not replace union Cell with just uint16_t because I want variables that model registers to be addressable as real registers are like (RAX/EAX)/AX/AL (no AH tho).

Reasons:
  • RegEx Blacklisted phrase (1): I want
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @chqrlie
  • Self-answer (0.5):
  • Low reputation (0.5):
Posted by: Andrey Dorofeev