Skip to content

Commit

Permalink
Fix Extended Asm ignored constraints
Browse files Browse the repository at this point in the history
This commit fixes the case where the register of for the Extended Asm
input or output is known. Before this commit, the following case:

  register long __a0 asm ("a0") = one;
  asm volatile (
       "ecall\n\t"
       : "+r" (__a0) // NOTE the +r here
  );

Didn't treat `a0` as an input+output register (+ contraint) as the code
skipped the constraint processing when the register was already chosen
(instead of allocated later).

This issue comes from f081acb, that was
taken as a reference in every other Extended Assembler implementation.
  • Loading branch information
ekaitz-zarraga committed Apr 16, 2024
1 parent 4944f50 commit 0703df1
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 8 deletions.
5 changes: 3 additions & 2 deletions arm-asm.c
Original file line number Diff line number Diff line change
Expand Up @@ -3075,7 +3075,6 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands,
tcc_error
("asm regvar requests register that's taken already");
reg = op->reg;
goto reg_found;
}
try_next:
c = *str++;
Expand All @@ -3095,7 +3094,9 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands,
case 'r': // general-purpose register
case 'p': // loadable/storable address
/* any general register */
for (reg = 0; reg <= 8; reg++) {
if ((reg = op->reg) >= 0)
goto reg_found;
else for (reg = 0; reg <= 8; reg++) {
if (!is_reg_allocated(reg))
goto reg_found;
}
Expand Down
12 changes: 9 additions & 3 deletions i386-asm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1342,7 +1342,6 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands,
if (is_reg_allocated(op->reg))
tcc_error("asm regvar requests register that's taken already");
reg = op->reg;
goto reg_found;
}
try_next:
c = *str++;
Expand Down Expand Up @@ -1385,12 +1384,17 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands,
case 'D':
reg = 7;
alloc_reg:
if (op->reg >= 0 && reg != op->reg)
goto try_next;
if (is_reg_allocated(reg))
goto try_next;
goto reg_found;
case 'q':
/* eax, ebx, ecx or edx */
for(reg = 0; reg < 4; reg++) {
if (op->reg >= 0) {
if ((reg = op->reg) < 4)
goto reg_found;
} else for(reg = 0; reg < 4; reg++) {
if (!is_reg_allocated(reg))
goto reg_found;
}
Expand All @@ -1399,7 +1403,9 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands,
case 'R':
case 'p': /* A general address, for x86(64) any register is acceptable*/
/* any general register */
for(reg = 0; reg < 8; reg++) {
if ((reg = op->reg) >= 0)
goto reg_found;
else for(reg = 0; reg < 8; reg++) {
if (!is_reg_allocated(reg))
goto reg_found;
}
Expand Down
9 changes: 6 additions & 3 deletions riscv64-asm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1720,7 +1720,6 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands,
tcc_error
("asm regvar requests register that's taken already");
reg = op->reg;
goto reg_found;
}
try_next:
c = *str++;
Expand All @@ -1739,7 +1738,9 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands,
case 'p': // loadable/storable address
/* any general register */
/* From a0 to a7 */
for (reg = 10; reg <= 18; reg++) {
if ((reg = op->reg) >= 0)
goto reg_found;
else for (reg = 10; reg <= 18; reg++) {
if (!is_reg_allocated(reg))
goto reg_found;
}
Expand All @@ -1753,7 +1754,9 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands,
case 'f': // floating pont register
/* floating point register */
/* From fa0 to fa7 */
for (reg = 42; reg <= 50; reg++) {
if ((reg = op->reg) >= 0)
goto reg_found;
else for (reg = 42; reg <= 50; reg++) {
if (!is_reg_allocated(reg))
goto reg_found;
}
Expand Down

0 comments on commit 0703df1

Please sign in to comment.