int immSize(PC origPC, int idx) { auto pc = origPC; auto const op = decode_op(pc); assert(idx >= 0 && idx < numImmediates(op)); always_assert(idx < 4); // No origPCs have more than four immediates static const int8_t argTypeToSizes[] = { #define ARGTYPE(nm, type) sizeof(type), #define ARGTYPEVEC(nm, type) 0, ARGTYPES #undef ARGTYPE #undef ARGTYPEVEC }; if (immType(op, idx) == IVA || immType(op, idx) == LA || immType(op, idx) == IA) { if (idx >= 1) pc += immSize(origPC, 0); if (idx >= 2) pc += immSize(origPC, 1); if (idx >= 3) pc += immSize(origPC, 2); auto const imm = decode_raw<uint8_t>(pc); // Low order bit set => 4-byte. return (imm & 0x1 ? sizeof(int32_t) : sizeof(unsigned char)); } if (immType(op, idx) == RATA) { if (idx >= 1) pc += immSize(origPC, 0); if (idx >= 2) pc += immSize(origPC, 1); if (idx >= 3) pc += immSize(origPC, 2); return encodedRATSize(pc); } if (immIsVector(op, idx)) { if (idx >= 1) pc += immSize(origPC, 0); if (idx >= 2) pc += immSize(origPC, 1); if (idx >= 3) pc += immSize(origPC, 2); int prefixes, vecElemSz; auto itype = immType(op, idx); if (itype == MA) { prefixes = 2; vecElemSz = sizeof(uint8_t); } else if (itype == BLA) { prefixes = 1; vecElemSz = sizeof(Offset); } else if (itype == ILA) { prefixes = 1; vecElemSz = 2 * sizeof(uint32_t); } else if (itype == VSA) { prefixes = 1; vecElemSz = sizeof(Id); } else { assert(itype == SLA); prefixes = 1; vecElemSz = sizeof(StrVecItem); } return prefixes * sizeof(int32_t) + vecElemSz * decode_raw<int32_t>(pc); } ArgType type = immType(op, idx); return (type >= 0) ? argTypeToSizes[type] : 0; }
int immSize(const Op* opcode, int idx) { assert(idx >= 0 && idx < numImmediates(*opcode)); always_assert(idx < 4); // No opcodes have more than four immediates static const int8_t argTypeToSizes[] = { #define ARGTYPE(nm, type) sizeof(type), #define ARGTYPEVEC(nm, type) 0, ARGTYPES #undef ARGTYPE #undef ARGTYPEVEC }; if (immType(*opcode, idx) == IVA || immType(*opcode, idx) == LA || immType(*opcode, idx) == IA) { intptr_t offset = 1; if (idx >= 1) offset += immSize(opcode, 0); if (idx >= 2) offset += immSize(opcode, 1); if (idx >= 3) offset += immSize(opcode, 2); unsigned char imm = *(const unsigned char*)(opcode + offset); // Low order bit set => 4-byte. return (imm & 0x1 ? sizeof(int32_t) : sizeof(unsigned char)); } if (immType(*opcode, idx) == RATA) { intptr_t offset = 1; if (idx >= 1) offset += immSize(opcode, 0); if (idx >= 2) offset += immSize(opcode, 1); if (idx >= 3) offset += immSize(opcode, 2); return encodedRATSize(reinterpret_cast<PC>(opcode) + offset); } if (immIsVector(*opcode, idx)) { intptr_t offset = 1; if (idx >= 1) offset += immSize(opcode, 0); if (idx >= 2) offset += immSize(opcode, 1); if (idx >= 3) offset += immSize(opcode, 2); int prefixes, vecElemSz; auto itype = immType(*opcode, idx); if (itype == MA) { prefixes = 2; vecElemSz = sizeof(uint8_t); } else if (itype == BLA) { prefixes = 1; vecElemSz = sizeof(Offset); } else if (itype == ILA) { prefixes = 1; vecElemSz = 2 * sizeof(uint32_t); } else if (itype == VSA) { prefixes = 1; vecElemSz = sizeof(Id); } else { assert(itype == SLA); prefixes = 1; vecElemSz = sizeof(StrVecItem); } return prefixes * sizeof(int32_t) + vecElemSz * *(int32_t*)((int8_t*)opcode + offset); } ArgType type = immType(*opcode, idx); return (type >= 0) ? argTypeToSizes[type] : 0; }
int immSize(PC origPC, int idx) { auto pc = origPC; auto const op = decode_op(pc); assert(idx >= 0 && idx < numImmediates(op)); always_assert(idx < 4); // No origPCs have more than four immediates static const int8_t argTypeToSizes[] = { #define ARGTYPE(nm, type) sizeof(type), #define ARGTYPEVEC(nm, type) 0, ARGTYPES #undef ARGTYPE #undef ARGTYPEVEC }; if (immType(op, idx) == IVA || immType(op, idx) == LA || immType(op, idx) == IA) { if (idx >= 1) pc += immSize(origPC, 0); if (idx >= 2) pc += immSize(origPC, 1); if (idx >= 3) pc += immSize(origPC, 2); return encoded_iva_size(decode_raw<uint8_t>(pc)); } if (immType(op, idx) == KA) { if (idx >= 1) pc += immSize(origPC, 0); if (idx >= 2) pc += immSize(origPC, 1); if (idx >= 3) pc += immSize(origPC, 2); switch (decode_raw<MemberCode>(pc)) { case MW: return 1; case MEL: case MPL: case MEC: case MPC: return 1 + encoded_iva_size(decode_raw<uint8_t>(pc)); case MEI: return 1 + sizeof(int64_t); case MET: case MPT: case MQT: return 1 + sizeof(Id); } not_reached(); } if (immType(op, idx) == RATA) { if (idx >= 1) pc += immSize(origPC, 0); if (idx >= 2) pc += immSize(origPC, 1); if (idx >= 3) pc += immSize(origPC, 2); return encodedRATSize(pc); } if (immIsVector(op, idx)) { if (idx >= 1) pc += immSize(origPC, 0); if (idx >= 2) pc += immSize(origPC, 1); if (idx >= 3) pc += immSize(origPC, 2); int vecElemSz; auto itype = immType(op, idx); if (itype == BLA) { vecElemSz = sizeof(Offset); } else if (itype == ILA) { vecElemSz = 2 * sizeof(uint32_t); } else if (itype == VSA) { vecElemSz = sizeof(Id); } else { assert(itype == SLA); vecElemSz = sizeof(StrVecItem); } return sizeof(int32_t) + vecElemSz * decode_raw<int32_t>(pc); } ArgType type = immType(op, idx); return (type >= 0) ? argTypeToSizes[type] : 0; }