* Send a `movsbl %r8,%r32' instruction. */
| 1219 | * Send a `movsbl %r8,%r32' instruction. |
| 1220 | */ |
| 1221 | void sendMovFromR8ToR64(FILE *out, int srcno, bool srchi, int dstno) |
| 1222 | { |
| 1223 | const uint8_t REX_MASK[] = |
| 1224 | {0, 0, 0, 0, 1, 1, 0, |
| 1225 | 0, 1, 1, 0, 0, 1, 1, 1, 1, 0}; |
| 1226 | const uint8_t REX[] = {0x48, 0x4c, 0x49, 0x4d}; |
| 1227 | const uint8_t REG[] = |
| 1228 | {0x07, 0x06, 0x02, 0x01, 0x00, 0x01, 0x00, |
| 1229 | 0x00, 0x02, 0x03, 0x03, 0x05, 0x04, 0x05, 0x06, 0x07, 0x04}; |
| 1230 | |
| 1231 | uint8_t rex = REX[(REX_MASK[srcno] << 1) | REX_MASK[dstno]]; |
| 1232 | bool xchg = false; |
| 1233 | uint8_t srcreg = REG[srcno]; |
| 1234 | if (rex == 0x00) |
| 1235 | { |
| 1236 | switch (srcno) |
| 1237 | { |
| 1238 | case RAX_IDX: case RBX_IDX: case RCX_IDX: case RDX_IDX: |
| 1239 | if (srchi) |
| 1240 | srcreg += 4; // Convert to %rh encoding |
| 1241 | break; |
| 1242 | case RDI_IDX: case RSI_IDX: case RSP_IDX: case RBP_IDX: |
| 1243 | rex = 0x40; break; |
| 1244 | default: |
| 1245 | break; |
| 1246 | } |
| 1247 | } |
| 1248 | else if (srchi) |
| 1249 | { |
| 1250 | // xchgb %rh,%rl |
| 1251 | xchg = true; |
| 1252 | switch (srcno) |
| 1253 | { |
| 1254 | case RAX_IDX: |
| 1255 | fprintf(out, "%u,%u,", 0x86, 0xe0); break; |
| 1256 | case RBX_IDX: |
| 1257 | fprintf(out, "%u,%u,", 0x86, 0xfb); break; |
| 1258 | case RCX_IDX: |
| 1259 | fprintf(out, "%u,%u,", 0x86, 0xe9); break; |
| 1260 | case RDX_IDX: |
| 1261 | fprintf(out, "%u,%u,", 0x86, 0xf2); break; |
| 1262 | } |
| 1263 | } |
| 1264 | uint8_t modrm = (0x03 << 6) | (REG[dstno] << 3) | srcreg; |
| 1265 | fprintf(out, "%u,%u,%u,%u,", rex, 0x0f, 0xbe, modrm); |
| 1266 | if (xchg) |
| 1267 | { |
| 1268 | // xchgb %rh,%rl |
| 1269 | switch (srcno) |
| 1270 | { |
| 1271 | case RAX_IDX: |
| 1272 | fprintf(out, "%u,%u,", 0x86, 0xe0); break; |
| 1273 | case RBX_IDX: |
| 1274 | fprintf(out, "%u,%u,", 0x86, 0xfb); break; |
| 1275 | case RCX_IDX: |
| 1276 | fprintf(out, "%u,%u,", 0x86, 0xe9); break; |
| 1277 | case RDX_IDX: |
| 1278 | fprintf(out, "%u,%u,", 0x86, 0xf2); break; |
no test coverage detected