aboutsummaryrefslogtreecommitdiff
path: root/x86_64-gen.c
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2016-10-03 05:20:21 +0200
committerMichael Matz <matz@suse.de>2016-12-15 17:47:12 +0100
commitad723a419fd956d984a0956713566453ba8f6a12 (patch)
tree545e85608c951f3416c79146a6c378435dfb0af1 /x86_64-gen.c
parentb5669a952babf486f0f8beb1e0a52d9031b3ae84 (diff)
downloadtinycc-ad723a419fd956d984a0956713566453ba8f6a12.tar.gz
tinycc-ad723a419fd956d984a0956713566453ba8f6a12.tar.bz2
x86_64: Add -mno-sse option
This disables generation of any SSE instructions (in particular in stdarg function prologues). Necessary for kernel compiles.
Diffstat (limited to 'x86_64-gen.c')
-rw-r--r--x86_64-gen.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/x86_64-gen.c b/x86_64-gen.c
index f5a2cdd..35ec1ab 100644
--- a/x86_64-gen.c
+++ b/x86_64-gen.c
@@ -851,6 +851,8 @@ void gfunc_call(int nb_args)
struct_size += size;
} else {
if (is_sse_float(vtop->type.t)) {
+ if (tcc_state->nosse)
+ tcc_error("SSE disabled");
gv(RC_XMM0); /* only use one float register */
if (arg >= REGN) {
/* movq %xmm0, j*8(%rsp) */
@@ -961,6 +963,8 @@ void gfunc_prolog(CType *func_type)
if (reg_param_index < REGN) {
/* save arguments passed by register */
if ((bt == VT_FLOAT) || (bt == VT_DOUBLE)) {
+ if (tcc_state->nosse)
+ tcc_error("SSE disabled");
o(0xd60f66); /* movq */
gen_modrm(reg_param_index, VT_LOCAL, NULL, addr);
} else {
@@ -1208,6 +1212,9 @@ void gfunc_call(int nb_args)
nb_reg_args += reg_count;
}
+ if (nb_sse_args && tcc_state->nosse)
+ tcc_error("SSE disabled but floating point arguments passed");
+
/* arguments are collected in runs. Each run is a collection of 8-byte aligned arguments
and ended by a 16-byte aligned argument. This is because, from the point of view of
the callee, argument alignment is computed from the bottom up. */
@@ -1541,8 +1548,10 @@ void gfunc_prolog(CType *func_type)
/* save all register passing arguments */
for (i = 0; i < 8; i++) {
loc -= 16;
- o(0xd60f66); /* movq */
- gen_modrm(7 - i, VT_LOCAL, NULL, loc);
+ if (!tcc_state->nosse) {
+ o(0xd60f66); /* movq */
+ gen_modrm(7 - i, VT_LOCAL, NULL, loc);
+ }
/* movq $0, loc+8(%rbp) */
o(0x85c748);
gen_le32(loc + 8);
@@ -1572,6 +1581,8 @@ void gfunc_prolog(CType *func_type)
mode = classify_x86_64_arg(type, NULL, &size, &align, &reg_count);
switch (mode) {
case x86_64_mode_sse:
+ if (tcc_state->nosse)
+ tcc_error("SSE disabled but floating point arguments used");
if (sse_param_index + reg_count <= 8) {
/* save arguments passed by register */
loc -= reg_count * 8;