summaryrefslogtreecommitdiffhomepage
path: root/ir/be/beasm.c
diff options
context:
space:
mode:
authorChristoph Mallon <christoph.mallon@gmx.de>2018-05-05 06:44:07 +0200
committerChristoph Mallon <christoph.mallon@gmx.de>2018-05-05 07:14:19 +0200
commitaadee603435ee0abad189a915f8d22f4c895cc52 (patch)
treee80cf166b1a3cd8ef1126da138e0ea0aa393ca12 /ir/be/beasm.c
parent82588751e05579fc6adf7b56e46af8eb873fff29 (diff)
be: Ignore clobbering of unusable registers.
This seems to be what gcc does. This fixes sparccode/clobbernames.c on sparc.
Diffstat (limited to 'ir/be/beasm.c')
-rw-r--r--ir/be/beasm.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/ir/be/beasm.c b/ir/be/beasm.c
index 73151ad..2efe56a 100644
--- a/ir/be/beasm.c
+++ b/ir/be/beasm.c
@@ -9,6 +9,7 @@
#include "bediagnostic.h"
#include "beemitter.h"
#include "begnuas.h"
+#include "beirg.h"
#include "benode.h"
#include "betranshlp.h"
#include "ident_t.h"
@@ -233,11 +234,14 @@ ir_node *be_make_asm(ir_node const *const node, ir_node **in, arch_register_req_
/* Collect clobbers and add them as outputs. */
unsigned clobber_bits[ir_target.isa->n_register_classes];
memset(&clobber_bits, 0, sizeof(clobber_bits));
- ident **const clobbers = get_ASM_clobbers(node);
+
+ be_irg_t *const birg = be_birg_from_irg(irg);
+ unsigned const *const allocatable_regs = birg->allocatable_regs;
+ ident **const clobbers = get_ASM_clobbers(node);
for (size_t i = 0; i < n_clobbers; ++i) {
char const *const clobber = get_id_str(clobbers[i]);
arch_register_t const *const reg = be_parse_register_name(clobber);
- if (reg) {
+ if (reg && rbitset_is_set(allocatable_regs, reg->global_index)) {
assert(reg->cls->n_regs <= sizeof(unsigned) * 8);
if (!reg->cls->allow_clobber_input)
clobber_bits[reg->cls->index] |= 1U << reg->index;