in pcre/sljit/sljitNativeTILEGX_64.c [1340:1531]
static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
{
sljit_s32 tmp_ar, base;
SLJIT_ASSERT(arg & SLJIT_MEM);
if (!(next_arg & SLJIT_MEM)) {
next_arg = 0;
next_argw = 0;
}
if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA))
tmp_ar = reg_ar;
else
tmp_ar = TMP_REG1_mapped;
base = arg & REG_MASK;
if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
argw &= 0x3;
if ((flags & WRITE_BACK) && reg_ar == reg_map[base]) {
SLJIT_ASSERT(!(flags & LOAD_DATA) && reg_map[TMP_REG1] != reg_ar);
FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO));
reg_ar = TMP_REG1_mapped;
}
/* Using the cache. */
if (argw == compiler->cache_argw) {
if (!(flags & WRITE_BACK)) {
if (arg == compiler->cache_arg) {
if (flags & LOAD_DATA)
return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
else
return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
}
if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
if (arg == next_arg && argw == (next_argw & 0x3)) {
compiler->cache_arg = arg;
compiler->cache_argw = argw;
FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], TMP_REG3_mapped));
if (flags & LOAD_DATA)
return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
else
return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
}
FAIL_IF(ADD(tmp_ar, reg_map[base], TMP_REG3_mapped));
if (flags & LOAD_DATA)
return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar);
else
return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar);
}
} else {
if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped));
if (flags & LOAD_DATA)
return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]);
else
return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar);
}
}
}
if (SLJIT_UNLIKELY(argw)) {
compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
compiler->cache_argw = argw;
FAIL_IF(SHLI(TMP_REG3_mapped, reg_map[OFFS_REG(arg)], argw));
}
if (!(flags & WRITE_BACK)) {
if (arg == next_arg && argw == (next_argw & 0x3)) {
compiler->cache_arg = arg;
compiler->cache_argw = argw;
FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3]));
tmp_ar = TMP_REG3_mapped;
} else
FAIL_IF(ADD(tmp_ar, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3]));
if (flags & LOAD_DATA)
return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar);
else
return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar);
}
FAIL_IF(ADD(reg_map[base], reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3]));
if (flags & LOAD_DATA)
return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]);
else
return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar);
}
if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) {
/* Update only applies if a base register exists. */
if (reg_ar == reg_map[base]) {
SLJIT_ASSERT(!(flags & LOAD_DATA) && TMP_REG1_mapped != reg_ar);
if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) {
FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[base], argw));
if (flags & LOAD_DATA)
FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped));
else
FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar));
if (argw)
return ADDLI(reg_map[base], reg_map[base], argw);
return SLJIT_SUCCESS;
}
FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO));
reg_ar = TMP_REG1_mapped;
}
if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) {
if (argw)
FAIL_IF(ADDLI(reg_map[base], reg_map[base], argw));
} else {
if (compiler->cache_arg == SLJIT_MEM
&& argw - compiler->cache_argw <= SIMM_16BIT_MAX
&& argw - compiler->cache_argw >= SIMM_16BIT_MIN) {
if (argw != compiler->cache_argw) {
FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw));
compiler->cache_argw = argw;
}
FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped));
} else {
compiler->cache_arg = SLJIT_MEM;
compiler->cache_argw = argw;
FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw));
FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped));
}
}
if (flags & LOAD_DATA)
return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]);
else
return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar);
}
if (compiler->cache_arg == arg
&& argw - compiler->cache_argw <= SIMM_16BIT_MAX
&& argw - compiler->cache_argw >= SIMM_16BIT_MIN) {
if (argw != compiler->cache_argw) {
FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw));
compiler->cache_argw = argw;
}
if (flags & LOAD_DATA)
return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
else
return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
}
if (compiler->cache_arg == SLJIT_MEM
&& argw - compiler->cache_argw <= SIMM_16BIT_MAX
&& argw - compiler->cache_argw >= SIMM_16BIT_MIN) {
if (argw != compiler->cache_argw)
FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw));
} else {
compiler->cache_arg = SLJIT_MEM;
FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw));
}
compiler->cache_argw = argw;
if (!base) {
if (flags & LOAD_DATA)
return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
else
return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
}
if (arg == next_arg
&& next_argw - argw <= SIMM_16BIT_MAX
&& next_argw - argw >= SIMM_16BIT_MIN) {
compiler->cache_arg = arg;
FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, reg_map[base]));
if (flags & LOAD_DATA)
return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
else
return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
}
FAIL_IF(ADD(tmp_ar, TMP_REG3_mapped, reg_map[base]));
if (flags & LOAD_DATA)
return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar);
else
return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar);
}