aboutsummaryrefslogtreecommitdiffstats
path: root/arm
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@college-de-france.fr>2019-06-17 14:22:22 +0200
committerXavier Leroy <xavierleroy@users.noreply.github.com>2019-06-17 17:19:05 +0200
commited0cfe4b38208f15763f2d1c0372c441a320ea56 (patch)
tree0b1d49bede1a0b9d3d1392809d354fefa5f695ef /arm
parent0a4e441a722c6aa9921ff47bd1a411e274e24047 (diff)
downloadcompcert-kvx-ed0cfe4b38208f15763f2d1c0372c441a320ea56.tar.gz
compcert-kvx-ed0cfe4b38208f15763f2d1c0372c441a320ea56.zip
Extended asm: print register names according to their types
When printing an extended asm code fragment, placeholders %n are replaced by register names. Currently we ignore the fact that some assemblers use different register names depending on the width of the data that resides in the register. For example, x86_64 uses %rax for a 64-bit quantity and %eax for a 32-bit quantity, but CompCert always prints %rax in extended asm statements. This is problematic if we want to use 32-bit integer instructions in extended asm, e.g. int x, y; asm("addl %1, %0", "=r"(x), "r"(y)); produces addl %rax, %rdx which is syntactically incorrect. Another example is ARM FP registers: D0 is a double-precision float, but S0 is a single-precision float. This commit partially solves this issue by taking into account the Cminor type of the asm parameter when printing the corresponding register. Continuing the previous example, int x, y; asm("addl %1, %0", "=r"(x), "r"(y)); now produces addl %eax, %edx This is not perfect yet: we use Cminor types, because this is all we have at hand, and not source C types, hence "char" and "short" parameters are still printed like "int" parameters, which is not good for x86. (I.e. we produce %eax where GCC might have produced %al or %ax.) We'll leave this issue open.
Diffstat (limited to 'arm')
-rw-r--r--arm/TargetPrinter.ml6
1 files changed, 3 insertions, 3 deletions
diff --git a/arm/TargetPrinter.ml b/arm/TargetPrinter.ml
index 3a0814e1..03e06a65 100644
--- a/arm/TargetPrinter.ml
+++ b/arm/TargetPrinter.ml
@@ -113,9 +113,9 @@ struct
let freg_single oc r = output_string oc (single_float_reg_name r)
let freg_param_single oc r = output_string oc (single_param_reg_name r)
- let preg oc = function
+ let preg_asm oc ty = function
| IR r -> ireg oc r
- | FR r -> freg oc r
+ | FR r -> if ty = Tsingle then freg_single oc r else freg oc r
| _ -> assert false
(* In Thumb2 mode, some arithmetic instructions have shorter encodings
@@ -480,7 +480,7 @@ struct
(P.to_int kind) (extern_atom txt) args
| EF_inline_asm(txt, sg, clob) ->
fprintf oc "%s begin inline assembly\n\t" comment;
- print_inline_asm preg oc (camlstring_of_coqstring txt) sg args res;
+ print_inline_asm preg_asm oc (camlstring_of_coqstring txt) sg args res;
fprintf oc "%s end inline assembly\n" comment
| _ ->
assert false