* emit REX byte */
| 155 | * emit REX byte |
| 156 | */ |
| 157 | static void |
| 158 | emit_rex(struct bpf_jit_state *st, uint32_t op, uint32_t reg, uint32_t rm) |
| 159 | { |
| 160 | uint8_t rex; |
| 161 | |
| 162 | /* mark operand registers as used*/ |
| 163 | USED(st->reguse, reg); |
| 164 | USED(st->reguse, rm); |
| 165 | |
| 166 | rex = 0; |
| 167 | if (BPF_CLASS(op) == EBPF_ALU64 || |
| 168 | op == (BPF_ST | BPF_MEM | EBPF_DW) || |
| 169 | op == (BPF_STX | BPF_MEM | EBPF_DW) || |
| 170 | op == (BPF_STX | EBPF_XADD | EBPF_DW) || |
| 171 | op == (BPF_LD | BPF_IMM | EBPF_DW) || |
| 172 | (BPF_CLASS(op) == BPF_LDX && |
| 173 | BPF_MODE(op) == BPF_MEM && |
| 174 | BPF_SIZE(op) != BPF_W)) |
| 175 | rex |= REX_W; |
| 176 | |
| 177 | if (IS_EXT_REG(reg)) |
| 178 | rex |= REX_R; |
| 179 | |
| 180 | if (IS_EXT_REG(rm)) |
| 181 | rex |= REX_B; |
| 182 | |
| 183 | /* store using SIL, DIL */ |
| 184 | if (op == (BPF_STX | BPF_MEM | BPF_B) && (reg == RDI || reg == RSI)) |
| 185 | rex |= REX_PREFIX; |
| 186 | |
| 187 | if (rex != 0) { |
| 188 | rex |= REX_PREFIX; |
| 189 | emit_bytes(st, &rex, sizeof(rex)); |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | /* |
| 194 | * emit MODRegRM byte |
no test coverage detected