Skip to content

Commit 6b8abd2

Browse files
committed
tcg: Introduce the 'z' constraint for a hardware zero register
For loongarch, mips, riscv and sparc, a zero register is available all the time. For aarch64, register index 31 depends on context: sometimes it is the stack pointer, and sometimes it is the zero register. Introduce a new general-purpose constraint which maps 0 to TCG_REG_ZERO, if defined. This differs from existing constant constraints in that const_arg[*] is recorded as false, indicating that the value is in a register. Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Signed-off-by: Richard Henderson <[email protected]>
1 parent bf455ec commit 6b8abd2

File tree

8 files changed

+37
-10
lines changed

8 files changed

+37
-10
lines changed

docs/devel/tcg-ops.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -927,7 +927,9 @@ operation uses a constant input constraint which does not allow all
927927
constants, it must also accept registers in order to have a fallback.
928928
The constraint '``i``' is defined generically to accept any constant.
929929
The constraint '``r``' is not defined generically, but is consistently
930-
used by each backend to indicate all registers.
930+
used by each backend to indicate all registers. If ``TCG_REG_ZERO``
931+
is defined by the backend, the constraint '``z``' is defined generically
932+
to map constant 0 to the hardware zero register.
931933

932934
The movi_i32 and movi_i64 operations must accept any constants.
933935

include/tcg/tcg.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,8 @@ void tb_target_set_jmp_target(const TranslationBlock *, int,
713713

714714
void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size);
715715

716-
#define TCG_CT_CONST 1 /* any constant of register size */
716+
#define TCG_CT_CONST 1 /* any constant of register size */
717+
#define TCG_CT_REG_ZERO 2 /* zero, in TCG_REG_ZERO */
717718

718719
typedef struct TCGArgConstraint {
719720
unsigned ct : 16;

tcg/aarch64/tcg-target.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ typedef enum {
4545
TCG_AREG0 = TCG_REG_X19,
4646
} TCGReg;
4747

48+
#define TCG_REG_ZERO TCG_REG_XZR
49+
4850
#define TCG_TARGET_NB_REGS 64
4951

5052
#endif /* AARCH64_TCG_TARGET_H */

tcg/loongarch64/tcg-target.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,6 @@ typedef enum {
8585
TCG_VEC_TMP0 = TCG_REG_V23,
8686
} TCGReg;
8787

88+
#define TCG_REG_ZERO TCG_REG_ZERO
89+
8890
#endif /* LOONGARCH_TCG_TARGET_H */

tcg/mips/tcg-target.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,6 @@ typedef enum {
7070
TCG_AREG0 = TCG_REG_S8,
7171
} TCGReg;
7272

73+
#define TCG_REG_ZERO TCG_REG_ZERO
74+
7375
#endif

tcg/riscv/tcg-target.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,6 @@ typedef enum {
5757
TCG_REG_TMP2 = TCG_REG_T4,
5858
} TCGReg;
5959

60+
#define TCG_REG_ZERO TCG_REG_ZERO
61+
6062
#endif

tcg/sparc64/tcg-target.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ typedef enum {
6464
TCG_REG_I7,
6565
} TCGReg;
6666

67-
#define TCG_AREG0 TCG_REG_I0
67+
#define TCG_AREG0 TCG_REG_I0
68+
#define TCG_REG_ZERO TCG_REG_G0
6869

6970
#endif

tcg/tcg.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3223,6 +3223,11 @@ static void process_constraint_sets(void)
32233223
case 'i':
32243224
args_ct[i].ct |= TCG_CT_CONST;
32253225
break;
3226+
#ifdef TCG_REG_ZERO
3227+
case 'z':
3228+
args_ct[i].ct |= TCG_CT_REG_ZERO;
3229+
break;
3230+
#endif
32263231

32273232
/* Include all of the target-specific constraints. */
32283233

@@ -5074,13 +5079,23 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
50745079
arg_ct = &args_ct[i];
50755080
ts = arg_temp(arg);
50765081

5077-
if (ts->val_type == TEMP_VAL_CONST
5078-
&& tcg_target_const_match(ts->val, arg_ct->ct, ts->type,
5079-
op_cond, TCGOP_VECE(op))) {
5080-
/* constant is OK for instruction */
5081-
const_args[i] = 1;
5082-
new_args[i] = ts->val;
5083-
continue;
5082+
if (ts->val_type == TEMP_VAL_CONST) {
5083+
#ifdef TCG_REG_ZERO
5084+
if (ts->val == 0 && (arg_ct->ct & TCG_CT_REG_ZERO)) {
5085+
/* Hardware zero register: indicate register via non-const. */
5086+
const_args[i] = 0;
5087+
new_args[i] = TCG_REG_ZERO;
5088+
continue;
5089+
}
5090+
#endif
5091+
5092+
if (tcg_target_const_match(ts->val, arg_ct->ct, ts->type,
5093+
op_cond, TCGOP_VECE(op))) {
5094+
/* constant is OK for instruction */
5095+
const_args[i] = 1;
5096+
new_args[i] = ts->val;
5097+
continue;
5098+
}
50845099
}
50855100

50865101
reg = ts->reg;

0 commit comments

Comments
 (0)