aboutsummaryrefslogtreecommitdiffhomepage
path: root/x86_64
diff options
context:
space:
mode:
Diffstat (limited to 'x86_64')
-rw-r--r--x86_64/emit.c2
-rw-r--r--x86_64/isel.c10
2 files changed, 7 insertions, 5 deletions
diff --git a/x86_64/emit.c b/x86_64/emit.c
index 0d7b77a..e54b7dd 100644
--- a/x86_64/emit.c
+++ b/x86_64/emit.c
@@ -880,7 +880,7 @@ gencopy(uchar **pcode, enum irclass cls, struct block *blk, int curi, struct ope
/* dst = 0 -> xor dst, dst; but only if it is ok to clobber flags */
Xxor(pcode, kisint(cls) ? KI32 : cls, dst, dst);
} else if (isaddrcon(val,0)) {
- if ((ccopt.pic || (contab.p[val.i].flag & SFUNC)) && !(contab.p[val.i].flag & SLOCAL)) {
+ if ((ccopt.pic || (contab.p[val.i].flag & SFUNC)) && (contab.p[val.i].flag & (SLOCAL|SFUNC)) != (SLOCAL|SFUNC)) {
GOTLoad:
/* for mov reg, [rip(sym@GOTPCREL)] */
Xmov(pcode, cls, dst, mkoper(OSYMGOT, .con = val.i, .cindex = NOINDEX));
diff --git a/x86_64/isel.c b/x86_64/isel.c
index 7f82984..c3857c7 100644
--- a/x86_64/isel.c
+++ b/x86_64/isel.c
@@ -90,8 +90,8 @@ fixarg(union ref *r, struct instr *ins, struct block *blk, int *curi)
}
if (docopy)
*r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, con->cls, *r));
- } else if (op != Omove && con->issym && ins && r == &ins->r) {
- *r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, mkaddr((struct addr){*r})));
+ } else if (op != Omove && (con->issym || (con->isdat && !con->deref)) && ins && r == &ins->r) {
+ *r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, *r));
} else if (in_range(op, Odiv, Ourem) && kisint(ins->cls))
goto DivImm;
} else if (r->t == RICON && in_range(op, Odiv, Ourem) && kisint(ins->cls) && r == &ins->r) {
@@ -107,6 +107,8 @@ fixarg(union ref *r, struct instr *ins, struct block *blk, int *curi)
*ins = adr;
else
*r = insertinstr(blk, (*curi)++, adr);
+ } else if (r->bits == UNDREF.bits && ins->op != Ocopy) {
+ *r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, ins->cls, *r));
}
picfixsym(r, blk, curi);
}
@@ -387,7 +389,7 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi)
case Ointrin:
break;
case Oshl: case Osar: case Oslr:
- if (!iscon(ins->r)) {
+ if (!isintcon(ins->r)) {
/* shift amount register is always CL */
insertinstr(blk, (*curi)++, mkinstr(Omove, KI32, mkref(RREG, RCX), ins->r));
ins->r = mkref(RREG, RCX);
@@ -396,7 +398,7 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi)
case Oequ: case Oneq:
case Olth: case Ogth: case Olte: case Ogte:
case Oulth: case Ougth: case Oulte: case Ougte:
- if (iscon(ins->l)) {
+ if (iscon(ins->l) && !iscon(ins->r)) {
/* lth imm, x -> gth x, imm */
if (!in_range(ins->op, Oequ, Oneq))
ins->op = ((op - Olth) ^ 1) + Olth;