diff options
author | Richard Henderson <rth@twiddle.net> | 2016-11-18 17:41:24 +0100 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2017-01-10 08:06:11 -0800 |
commit | 17280ff4a5f264e01e55ae514ee6d3586f9577b2 (patch) | |
tree | 3b100116b70367a5b3f01e117dcfbd029bbdd1e1 /tcg/tcg.c | |
parent | 069ea736b50b75fdec99c9b8cc603b97bd98419e (diff) |
tcg: Allow an operand to be matching or a constant
This allows an output operand to match an input operand
only when the input operand needs a register.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'tcg/tcg.c')
-rw-r--r-- | tcg/tcg.c | 63 |
1 files changed, 32 insertions, 31 deletions
@@ -1256,37 +1256,37 @@ static void process_op_defs(TCGContext *s) tcg_regset_clear(def->args_ct[i].u.regs); def->args_ct[i].ct = 0; - if (ct_str[0] >= '0' && ct_str[0] <= '9') { - int oarg; - oarg = ct_str[0] - '0'; - tcg_debug_assert(oarg < def->nb_oargs); - tcg_debug_assert(def->args_ct[oarg].ct & TCG_CT_REG); - /* TCG_CT_ALIAS is for the output arguments. The input - argument is tagged with TCG_CT_IALIAS. */ - def->args_ct[i] = def->args_ct[oarg]; - def->args_ct[oarg].ct = TCG_CT_ALIAS; - def->args_ct[oarg].alias_index = i; - def->args_ct[i].ct |= TCG_CT_IALIAS; - def->args_ct[i].alias_index = oarg; - } else { - for(;;) { - if (*ct_str == '\0') - break; - switch(*ct_str) { - case '&': - def->args_ct[i].ct |= TCG_CT_NEWREG; - ct_str++; - break; - case 'i': - def->args_ct[i].ct |= TCG_CT_CONST; - ct_str++; - break; - default: - ct_str = target_parse_constraint(&def->args_ct[i], - ct_str, type); - /* Typo in TCGTargetOpDef constraint. */ - tcg_debug_assert(ct_str != NULL); + while (*ct_str != '\0') { + switch(*ct_str) { + case '0' ... '9': + { + int oarg = *ct_str - '0'; + tcg_debug_assert(ct_str == tdefs->args_ct_str[i]); + tcg_debug_assert(oarg < def->nb_oargs); + tcg_debug_assert(def->args_ct[oarg].ct & TCG_CT_REG); + /* TCG_CT_ALIAS is for the output arguments. + The input is tagged with TCG_CT_IALIAS. */ + def->args_ct[i] = def->args_ct[oarg]; + def->args_ct[oarg].ct |= TCG_CT_ALIAS; + def->args_ct[oarg].alias_index = i; + def->args_ct[i].ct |= TCG_CT_IALIAS; + def->args_ct[i].alias_index = oarg; } + ct_str++; + break; + case '&': + def->args_ct[i].ct |= TCG_CT_NEWREG; + ct_str++; + break; + case 'i': + def->args_ct[i].ct |= TCG_CT_CONST; + ct_str++; + break; + default: + ct_str = target_parse_constraint(&def->args_ct[i], + ct_str, type); + /* Typo in TCGTargetOpDef constraint. */ + tcg_debug_assert(ct_str != NULL); } } } @@ -2296,7 +2296,8 @@ static void tcg_reg_alloc_op(TCGContext *s, arg = args[i]; arg_ct = &def->args_ct[i]; ts = &s->temps[arg]; - if (arg_ct->ct & TCG_CT_ALIAS) { + if ((arg_ct->ct & TCG_CT_ALIAS) + && !const_args[arg_ct->alias_index]) { reg = new_args[arg_ct->alias_index]; } else if (arg_ct->ct & TCG_CT_NEWREG) { reg = tcg_reg_alloc(s, arg_ct->u.regs, |