Lines Matching refs:src_reg

228 /* Encode 'dst_reg' and 'src_reg' registers into x86-64 opcode 'byte' */
229 static u8 add_2reg(u8 byte, u32 dst_reg, u32 src_reg)
231 return byte + reg2hex[dst_reg] + (reg2hex[src_reg] << 3);
839 static void emit_mov_reg(u8 **pprog, bool is64, u32 dst_reg, u32 src_reg)
845 EMIT_mov(dst_reg, src_reg);
848 if (is_ereg(dst_reg) || is_ereg(src_reg))
849 EMIT1(add_2mod(0x40, dst_reg, src_reg));
850 EMIT2(0x89, add_2reg(0xC0, dst_reg, src_reg));
857 u32 src_reg)
864 EMIT4(add_2mod(0x48, src_reg, dst_reg), 0x0f, 0xbe,
865 add_2reg(0xC0, src_reg, dst_reg));
867 EMIT4(add_2mod(0x48, src_reg, dst_reg), 0x0f, 0xbf,
868 add_2reg(0xC0, src_reg, dst_reg));
870 EMIT3(add_2mod(0x48, src_reg, dst_reg), 0x63,
871 add_2reg(0xC0, src_reg, dst_reg));
875 EMIT4(add_2mod(0x40, src_reg, dst_reg), 0x0f, 0xbe,
876 add_2reg(0xC0, src_reg, dst_reg));
878 if (is_ereg(dst_reg) || is_ereg(src_reg))
879 EMIT1(add_2mod(0x40, src_reg, dst_reg));
880 EMIT3(add_2mod(0x0f, src_reg, dst_reg), 0xbf,
881 add_2reg(0xC0, src_reg, dst_reg));
923 static void maybe_emit_mod(u8 **pprog, u32 dst_reg, u32 src_reg, bool is64)
928 EMIT1(add_2mod(0x48, dst_reg, src_reg));
929 else if (is_ereg(dst_reg) || is_ereg(src_reg))
930 EMIT1(add_2mod(0x40, dst_reg, src_reg));
948 /* LDX: dst_reg = *(u8*)(src_reg + off) */
949 static void emit_ldx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
956 EMIT3(add_2mod(0x48, src_reg, dst_reg), 0x0F, 0xB6);
960 EMIT3(add_2mod(0x48, src_reg, dst_reg), 0x0F, 0xB7);
964 if (is_ereg(dst_reg) || is_ereg(src_reg))
965 EMIT2(add_2mod(0x40, src_reg, dst_reg), 0x8B);
971 EMIT2(add_2mod(0x48, src_reg, dst_reg), 0x8B);
974 emit_insn_suffix(&prog, src_reg, dst_reg, off);
978 /* LDSX: dst_reg = *(s8*)(src_reg + off) */
979 static void emit_ldsx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
986 EMIT3(add_2mod(0x48, src_reg, dst_reg), 0x0F, 0xBE);
990 EMIT3(add_2mod(0x48, src_reg, dst_reg), 0x0F, 0xBF);
994 EMIT2(add_2mod(0x48, src_reg, dst_reg), 0x63);
997 emit_insn_suffix(&prog, src_reg, dst_reg, off);
1001 static void emit_ldx_index(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, u32 index_reg, int off)
1008 EMIT3(add_3mod(0x40, src_reg, dst_reg, index_reg), 0x0F, 0xB6);
1012 EMIT3(add_3mod(0x40, src_reg, dst_reg, index_reg), 0x0F, 0xB7);
1016 EMIT2(add_3mod(0x40, src_reg, dst_reg, index_reg), 0x8B);
1020 EMIT2(add_3mod(0x48, src_reg, dst_reg, index_reg), 0x8B);
1023 emit_insn_suffix_SIB(&prog, src_reg, dst_reg, index_reg, off);
1027 static void emit_ldx_r12(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
1029 emit_ldx_index(pprog, size, dst_reg, src_reg, X86_REG_R12, off);
1032 /* STX: *(u8*)(dst_reg + off) = src_reg */
1033 static void emit_stx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
1040 if (is_ereg(dst_reg) || is_ereg_8l(src_reg))
1041 /* Add extra byte for eregs or SIL,DIL,BPL in src_reg */
1042 EMIT2(add_2mod(0x40, dst_reg, src_reg), 0x88);
1047 if (is_ereg(dst_reg) || is_ereg(src_reg))
1048 EMIT3(0x66, add_2mod(0x40, dst_reg, src_reg), 0x89);
1053 if (is_ereg(dst_reg) || is_ereg(src_reg))
1054 EMIT2(add_2mod(0x40, dst_reg, src_reg), 0x89);
1059 EMIT2(add_2mod(0x48, dst_reg, src_reg), 0x89);
1062 emit_insn_suffix(&prog, dst_reg, src_reg, off);
1066 /* STX: *(u8*)(dst_reg + index_reg + off) = src_reg */
1067 static void emit_stx_index(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, u32 index_reg, int off)
1074 EMIT2(add_3mod(0x40, dst_reg, src_reg, index_reg), 0x88);
1078 EMIT3(0x66, add_3mod(0x40, dst_reg, src_reg, index_reg), 0x89);
1082 EMIT2(add_3mod(0x40, dst_reg, src_reg, index_reg), 0x89);
1086 EMIT2(add_3mod(0x48, dst_reg, src_reg, index_reg), 0x89);
1089 emit_insn_suffix_SIB(&prog, dst_reg, src_reg, index_reg, off);
1093 static void emit_stx_r12(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
1095 emit_stx_index(pprog, size, dst_reg, src_reg, X86_REG_R12, off);
1132 u32 dst_reg, u32 src_reg, s16 off, u8 bpf_size)
1138 maybe_emit_mod(&prog, dst_reg, src_reg, bpf_size == BPF_DW);
1146 /* lock *(u32/u64*)(dst_reg + off) <op>= src_reg */
1150 /* src_reg = atomic_fetch_add(dst_reg + off, src_reg); */
1154 /* src_reg = atomic_xchg(dst_reg + off, src_reg); */
1158 /* r0 = atomic_cmpxchg(dst_reg + off, r0, src_reg); */
1166 emit_insn_suffix(&prog, dst_reg, src_reg, off);
1193 if (insn->dst_reg == BPF_REG_6 || insn->src_reg == BPF_REG_6)
1195 if (insn->dst_reg == BPF_REG_7 || insn->src_reg == BPF_REG_7)
1197 if (insn->dst_reg == BPF_REG_8 || insn->src_reg == BPF_REG_8)
1199 if (insn->dst_reg == BPF_REG_9 || insn->src_reg == BPF_REG_9)
1252 static void emit_shiftx(u8 **pprog, u32 dst_reg, u8 src_reg, bool is64, u8 op)
1258 emit_3vex(&prog, r, false, r, m, is64, src_reg, false, op);
1326 u32 src_reg = insn->src_reg;
1347 maybe_emit_mod(&prog, dst_reg, src_reg,
1350 EMIT2(b2, add_2reg(0xC0, dst_reg, src_reg));
1356 if (dst_reg != src_reg)
1358 emit_mov_reg(&prog, false, dst_reg, src_reg);
1392 dst_reg, src_reg);
1396 dst_reg, src_reg);
1484 if (src_reg == BPF_REG_0 ||
1485 src_reg == BPF_REG_3) {
1486 /* mov r11, src_reg */
1487 EMIT_mov(AUX_REG, src_reg);
1488 src_reg = AUX_REG;
1493 src_reg = AUX_REG;
1507 /* div src_reg */
1508 maybe_emit_1mod(&prog, src_reg, is64);
1509 EMIT2(0xF7, add_1reg(0xF0, src_reg));
1516 /* idiv src_reg */
1517 maybe_emit_1mod(&prog, src_reg, is64);
1518 EMIT2(0xF7, add_1reg(0xF8, src_reg));
1555 maybe_emit_mod(&prog, src_reg, dst_reg,
1558 /* imul dst_reg, src_reg */
1559 EMIT3(0x0F, 0xAF, add_2reg(0xC0, src_reg, dst_reg));
1586 if (boot_cpu_has(X86_FEATURE_BMI2) && src_reg != BPF_REG_4) {
1587 /* shrx/sarx/shlx dst_reg, dst_reg, src_reg */
1603 emit_shiftx(&prog, dst_reg, src_reg, w, op);
1608 if (src_reg != BPF_REG_4) { /* common case */
1617 /* mov rcx, src_reg */
1618 EMIT_mov(BPF_REG_4, src_reg);
1628 if (src_reg != BPF_REG_4) {
1731 /* STX: *(u8*)(dst_reg + off) = src_reg */
1736 emit_stx(&prog, BPF_SIZE(insn->code), dst_reg, src_reg, insn->off);
1747 /* LDX: dst_reg = *(u8*)(src_reg + r12 + off) */
1758 emit_ldx_r12(&prog, BPF_SIZE(insn->code), dst_reg, src_reg, insn->off);
1760 emit_stx_r12(&prog, BPF_SIZE(insn->code), dst_reg, src_reg, insn->off);
1789 /* LDX: dst_reg = *(u8*)(src_reg + off) */
1798 /* LDXS: dst_reg = *(s8*)(src_reg + off) */
1809 /* Conservatively check that src_reg + insn->off is a kernel address:
1810 * src_reg + insn->off >= TASK_SIZE_MAX + PAGE_SIZE
1811 * src_reg is used as scratch for src_reg += insn->off and restored
1819 * to src_reg, so no need to do relative load with insn->off offset
1829 /* add src_reg, insn->off */
1830 maybe_emit_1mod(&prog, src_reg, true);
1831 EMIT2_off32(0x81, add_1reg(0xC0, src_reg), insn->off);
1834 /* cmp src_reg, r11 */
1835 maybe_emit_mod(&prog, src_reg, AUX_REG, true);
1836 EMIT2(0x39, add_2reg(0xC0, src_reg, AUX_REG));
1853 emit_ldsx(&prog, BPF_SIZE(insn->code), dst_reg, src_reg, insn_off);
1855 emit_ldx(&prog, BPF_SIZE(insn->code), dst_reg, src_reg, insn_off);
1865 if (insn->off && src_reg != dst_reg) {
1866 /* sub src_reg, insn->off
1867 * Restore src_reg after "add src_reg, insn->off" in prev
1868 * if statement. But if src_reg == dst_reg, emit_ldx
1869 * above already clobbered src_reg, so no need to restore.
1870 * If add src_reg, insn->off was unnecessary, no need to
1873 maybe_emit_1mod(&prog, src_reg, true);
1874 EMIT2_off32(0x81, add_1reg(0xE8, src_reg), insn->off);
1920 u32 real_src_reg = src_reg;
1931 if (src_reg == BPF_REG_0)
1967 err = emit_atomic(&prog, insn->imm, dst_reg, src_reg,
2028 /* cmp dst_reg, src_reg */
2029 maybe_emit_mod(&prog, dst_reg, src_reg,
2031 EMIT2(0x39, add_2reg(0xC0, dst_reg, src_reg));
2036 /* test dst_reg, src_reg */
2037 maybe_emit_mod(&prog, dst_reg, src_reg,
2039 EMIT2(0x85, add_2reg(0xC0, dst_reg, src_reg));