mirror of
https://github.com/golang/go
synced 2024-11-13 16:50:23 -07:00
cmd/8g: factor out prog information
Like CL 12637051, but for 8g instead of 6g. Fix a few minor 6g errors too. R=ken2 CC=golang-dev https://golang.org/cl/12778043
This commit is contained in:
parent
8eb8ad2454
commit
ac0df6ce89
@ -1,3 +1,7 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "gg.h"
|
||||
@ -35,6 +39,11 @@ static ProgInfo progtable[ALAST] = {
|
||||
[AFUNCDATA]= {Pseudo},
|
||||
[APCDATA]= {Pseudo},
|
||||
|
||||
// NOP is an internal no-op that also stands
|
||||
// for USED and SET annotations, not the Intel opcode.
|
||||
[ANOP]= {LeftRead | RightWrite},
|
||||
|
||||
|
||||
[AADCL]= {SizeL | LeftRead | RightRdwr | SetCarry | UseCarry},
|
||||
[AADCQ]= {SizeQ | LeftRead | RightRdwr | SetCarry | UseCarry},
|
||||
[AADCW]= {SizeW | LeftRead | RightRdwr | SetCarry | UseCarry},
|
||||
@ -176,13 +185,10 @@ static ProgInfo progtable[ALAST] = {
|
||||
[ANEGQ]= {SizeQ | RightRdwr | SetCarry},
|
||||
[ANEGW]= {SizeW | RightRdwr | SetCarry},
|
||||
|
||||
// NOP is the opcode for USED and SET annotations, not the Intel opcode.
|
||||
[ANOP]= {LeftRead | RightWrite},
|
||||
|
||||
[ANOTB]= {SizeB | RightRdwr},
|
||||
[ANOTL]= {SizeL | RightRdwr},
|
||||
[ANOTQ]= {SizeQ | RightRdwr},
|
||||
[ANOTW]= {SizeQ | RightRdwr},
|
||||
[ANOTW]= {SizeW | RightRdwr},
|
||||
|
||||
[AORB]= {SizeB | LeftRead | RightRdwr | SetCarry},
|
||||
[AORL]= {SizeL | LeftRead | RightRdwr | SetCarry},
|
||||
@ -190,7 +196,7 @@ static ProgInfo progtable[ALAST] = {
|
||||
[AORW]= {SizeW | LeftRead | RightRdwr | SetCarry},
|
||||
|
||||
[APOPQ]= {SizeQ | RightWrite},
|
||||
[APUSHQ]= {SizeQ | RightWrite},
|
||||
[APUSHQ]= {SizeQ | LeftRead},
|
||||
|
||||
[ARCLB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
|
||||
[ARCLL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
|
||||
|
@ -168,3 +168,64 @@ int BtoR(int32);
|
||||
int BtoF(int32);
|
||||
|
||||
#pragma varargck type "D" Adr*
|
||||
|
||||
/*
|
||||
* prog.c
|
||||
*/
|
||||
typedef struct ProgInfo ProgInfo;
|
||||
struct ProgInfo
|
||||
{
|
||||
uint32 flags; // the bits below
|
||||
uint32 reguse; // required registers used by this instruction
|
||||
uint32 regset; // required registers set by this instruction
|
||||
uint32 regindex; // registers used by addressing mode
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
// Pseudo-op, like TEXT, GLOBL, TYPE, PCDATA, FUNCDATA.
|
||||
Pseudo = 1<<1,
|
||||
|
||||
// There's nothing to say about the instruction,
|
||||
// but it's still okay to see.
|
||||
OK = 1<<2,
|
||||
|
||||
// Size of right-side write, or right-side read if no write.
|
||||
SizeB = 1<<3,
|
||||
SizeW = 1<<4,
|
||||
SizeL = 1<<5,
|
||||
SizeQ = 1<<6,
|
||||
SizeF = 1<<7, // float aka float32
|
||||
SizeD = 1<<8, // double aka float64
|
||||
|
||||
// Left side: address taken, read, write.
|
||||
LeftAddr = 1<<9,
|
||||
LeftRead = 1<<10,
|
||||
LeftWrite = 1<<11,
|
||||
|
||||
// Right side: address taken, read, write.
|
||||
RightAddr = 1<<12,
|
||||
RightRead = 1<<13,
|
||||
RightWrite = 1<<14,
|
||||
|
||||
// Set, use, or kill of carry bit.
|
||||
// Kill means we never look at the carry bit after this kind of instruction.
|
||||
SetCarry = 1<<15,
|
||||
UseCarry = 1<<16,
|
||||
KillCarry = 1<<17,
|
||||
|
||||
// Instruction kinds
|
||||
Move = 1<<18, // straight move
|
||||
Conv = 1<<19, // size conversion
|
||||
Cjmp = 1<<20, // conditional jump
|
||||
Break = 1<<21, // breaks control flow (no fallthrough)
|
||||
Call = 1<<22, // function call
|
||||
Jump = 1<<23, // jump
|
||||
Skip = 1<<24, // data instruction
|
||||
|
||||
// Special cases for register use.
|
||||
ShiftCX = 1<<25, // possible shift by CX
|
||||
ImulAXDX = 1<<26, // possible multiply into DX:AX
|
||||
};
|
||||
|
||||
void proginfo(ProgInfo*, Prog*);
|
||||
|
@ -42,28 +42,14 @@ static void elimshortmov(Reg *r);
|
||||
static int
|
||||
needc(Prog *p)
|
||||
{
|
||||
ProgInfo info;
|
||||
|
||||
while(p != P) {
|
||||
switch(p->as) {
|
||||
case AADCL:
|
||||
case ASBBL:
|
||||
case ARCRB:
|
||||
case ARCRW:
|
||||
case ARCRL:
|
||||
proginfo(&info, p);
|
||||
if(info.flags & UseCarry)
|
||||
return 1;
|
||||
case AADDB:
|
||||
case AADDW:
|
||||
case AADDL:
|
||||
case ASUBB:
|
||||
case ASUBW:
|
||||
case ASUBL:
|
||||
case AJMP:
|
||||
case ARET:
|
||||
case ACALL:
|
||||
if(info.flags & (SetCarry|KillCarry))
|
||||
return 0;
|
||||
default:
|
||||
if(p->to.type == D_BRANCH)
|
||||
return 0;
|
||||
}
|
||||
p = p->link;
|
||||
}
|
||||
return 0;
|
||||
@ -94,19 +80,20 @@ peep(void)
|
||||
Reg *r, *r1, *r2;
|
||||
Prog *p, *p1;
|
||||
int t;
|
||||
ProgInfo info;
|
||||
|
||||
/*
|
||||
* complete R structure
|
||||
*/
|
||||
t = 0;
|
||||
for(r=firstr; r!=R; r=r1) {
|
||||
r1 = r->link;
|
||||
if(r1 == R)
|
||||
break;
|
||||
p = r->prog->link;
|
||||
while(p != r1->prog)
|
||||
switch(p->as) {
|
||||
default:
|
||||
for(p = r->prog->link; p != r1->prog; p = p->link) {
|
||||
proginfo(&info, p);
|
||||
if(info.flags & Skip)
|
||||
continue;
|
||||
|
||||
r2 = rega();
|
||||
r->link = r2;
|
||||
r2->link = r1;
|
||||
@ -120,14 +107,6 @@ peep(void)
|
||||
r1->p1 = r2;
|
||||
|
||||
r = r2;
|
||||
t++;
|
||||
|
||||
case ADATA:
|
||||
case AGLOBL:
|
||||
case ANAME:
|
||||
case ASIGNAME:
|
||||
case ATYPE:
|
||||
p = p->link;
|
||||
}
|
||||
}
|
||||
|
||||
@ -437,6 +416,7 @@ subprop(Reg *r0)
|
||||
Adr *v1, *v2;
|
||||
Reg *r;
|
||||
int t;
|
||||
ProgInfo info;
|
||||
|
||||
p = r0->prog;
|
||||
v1 = &p->from;
|
||||
@ -446,85 +426,24 @@ subprop(Reg *r0)
|
||||
if(!regtyp(v2))
|
||||
return 0;
|
||||
for(r=uniqp(r0); r!=R; r=uniqp(r)) {
|
||||
if(debug['P'] && debug['v'])
|
||||
print("\t? %P\n", r->prog);
|
||||
if(uniqs(r) == R)
|
||||
break;
|
||||
p = r->prog;
|
||||
switch(p->as) {
|
||||
case ACALL:
|
||||
proginfo(&info, p);
|
||||
if(info.flags & Call)
|
||||
return 0;
|
||||
|
||||
case AIMULL:
|
||||
case AIMULW:
|
||||
if(p->to.type != D_NONE)
|
||||
break;
|
||||
|
||||
case ARCLB:
|
||||
case ARCLL:
|
||||
case ARCLW:
|
||||
case ARCRB:
|
||||
case ARCRL:
|
||||
case ARCRW:
|
||||
case AROLB:
|
||||
case AROLL:
|
||||
case AROLW:
|
||||
case ARORB:
|
||||
case ARORL:
|
||||
case ARORW:
|
||||
case ASALB:
|
||||
case ASALL:
|
||||
case ASALW:
|
||||
case ASARB:
|
||||
case ASARL:
|
||||
case ASARW:
|
||||
case ASHLB:
|
||||
case ASHLL:
|
||||
case ASHLW:
|
||||
case ASHRB:
|
||||
case ASHRL:
|
||||
case ASHRW:
|
||||
if(p->from.type == D_CONST)
|
||||
break;
|
||||
|
||||
case ADIVB:
|
||||
case ADIVL:
|
||||
case ADIVW:
|
||||
case AIDIVB:
|
||||
case AIDIVL:
|
||||
case AIDIVW:
|
||||
case AIMULB:
|
||||
case AMULB:
|
||||
case AMULL:
|
||||
case AMULW:
|
||||
|
||||
case AREP:
|
||||
case AREPN:
|
||||
|
||||
case ACWD:
|
||||
case ACDQ:
|
||||
|
||||
case ASTOSB:
|
||||
case ASTOSL:
|
||||
case AMOVSB:
|
||||
case AMOVSL:
|
||||
|
||||
case AFMOVF:
|
||||
case AFMOVD:
|
||||
case AFMOVFP:
|
||||
case AFMOVDP:
|
||||
if(info.reguse | info.regset)
|
||||
return 0;
|
||||
|
||||
case AMOVL:
|
||||
case AMOVSS:
|
||||
case AMOVSD:
|
||||
if(p->to.type == v1->type)
|
||||
if((info.flags & Move) && (info.flags & (SizeL|SizeQ|SizeF|SizeD)) && p->to.type == v1->type)
|
||||
goto gotit;
|
||||
|
||||
if(copyau(&p->from, v2) || copyau(&p->to, v2))
|
||||
break;
|
||||
}
|
||||
if(copyau(&p->from, v2) ||
|
||||
copyau(&p->to, v2))
|
||||
break;
|
||||
if(copysub(&p->from, v1, v2, 0) ||
|
||||
copysub(&p->to, v1, v2, 0))
|
||||
if(copysub(&p->from, v1, v2, 0) || copysub(&p->to, v1, v2, 0))
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@ -669,215 +588,10 @@ copy1(Adr *v1, Adr *v2, Reg *r, int f)
|
||||
int
|
||||
copyu(Prog *p, Adr *v, Adr *s)
|
||||
{
|
||||
ProgInfo info;
|
||||
|
||||
switch(p->as) {
|
||||
|
||||
default:
|
||||
if(debug['P'])
|
||||
print("unknown op %A\n", p->as);
|
||||
/* SBBL; ADCL; FLD1; SAHF */
|
||||
return 2;
|
||||
|
||||
|
||||
case ANEGB:
|
||||
case ANEGW:
|
||||
case ANEGL:
|
||||
case ANOTB:
|
||||
case ANOTW:
|
||||
case ANOTL:
|
||||
if(copyas(&p->to, v))
|
||||
return 2;
|
||||
break;
|
||||
|
||||
case ALEAL: /* lhs addr, rhs store */
|
||||
if(copyas(&p->from, v))
|
||||
return 2;
|
||||
|
||||
|
||||
case ANOP: /* rhs store */
|
||||
case AMOVL:
|
||||
case AMOVBLSX:
|
||||
case AMOVBLZX:
|
||||
case AMOVWLSX:
|
||||
case AMOVWLZX:
|
||||
|
||||
case AMOVSS:
|
||||
case AMOVSD:
|
||||
case ACVTSD2SL:
|
||||
case ACVTSD2SS:
|
||||
case ACVTSL2SD:
|
||||
case ACVTSL2SS:
|
||||
case ACVTSS2SD:
|
||||
case ACVTSS2SL:
|
||||
case ACVTTSD2SL:
|
||||
case ACVTTSS2SL:
|
||||
if(copyas(&p->to, v)) {
|
||||
if(s != A)
|
||||
return copysub(&p->from, v, s, 1);
|
||||
if(copyau(&p->from, v))
|
||||
return 4;
|
||||
return 3;
|
||||
}
|
||||
goto caseread;
|
||||
|
||||
case ARCLB:
|
||||
case ARCLL:
|
||||
case ARCLW:
|
||||
case ARCRB:
|
||||
case ARCRL:
|
||||
case ARCRW:
|
||||
case AROLB:
|
||||
case AROLL:
|
||||
case AROLW:
|
||||
case ARORB:
|
||||
case ARORL:
|
||||
case ARORW:
|
||||
case ASALB:
|
||||
case ASALL:
|
||||
case ASALW:
|
||||
case ASARB:
|
||||
case ASARL:
|
||||
case ASARW:
|
||||
case ASHLB:
|
||||
case ASHLL:
|
||||
case ASHLW:
|
||||
case ASHRB:
|
||||
case ASHRL:
|
||||
case ASHRW:
|
||||
if(copyas(&p->to, v))
|
||||
return 2;
|
||||
if(copyas(&p->from, v))
|
||||
if(p->from.type == D_CX)
|
||||
return 2;
|
||||
goto caseread;
|
||||
|
||||
case AADDB: /* rhs rar */
|
||||
case AADDL:
|
||||
case AADDW:
|
||||
case AANDB:
|
||||
case AANDL:
|
||||
case AANDW:
|
||||
case ADECL:
|
||||
case ADECW:
|
||||
case AINCL:
|
||||
case AINCW:
|
||||
case ASUBB:
|
||||
case ASUBL:
|
||||
case ASUBW:
|
||||
case AORB:
|
||||
case AORL:
|
||||
case AORW:
|
||||
case AXORB:
|
||||
case AXORL:
|
||||
case AXORW:
|
||||
case AMOVB:
|
||||
case AMOVW:
|
||||
|
||||
case AADDSD:
|
||||
case AADDSS:
|
||||
case ACMPSD:
|
||||
case ACMPSS:
|
||||
case ADIVSD:
|
||||
case ADIVSS:
|
||||
case AMAXSD:
|
||||
case AMAXSS:
|
||||
case AMINSD:
|
||||
case AMINSS:
|
||||
case AMULSD:
|
||||
case AMULSS:
|
||||
case ARCPSS:
|
||||
case ARSQRTSS:
|
||||
case ASQRTSD:
|
||||
case ASQRTSS:
|
||||
case ASUBSD:
|
||||
case ASUBSS:
|
||||
case AXORPD:
|
||||
if(copyas(&p->to, v))
|
||||
return 2;
|
||||
goto caseread;
|
||||
|
||||
case ACMPL: /* read only */
|
||||
case ACMPW:
|
||||
case ACMPB:
|
||||
|
||||
case ACOMISD:
|
||||
case ACOMISS:
|
||||
case AUCOMISD:
|
||||
case AUCOMISS:
|
||||
caseread:
|
||||
if(s != A) {
|
||||
if(copysub(&p->from, v, s, 1))
|
||||
return 1;
|
||||
return copysub(&p->to, v, s, 1);
|
||||
}
|
||||
if(copyau(&p->from, v))
|
||||
return 1;
|
||||
if(copyau(&p->to, v))
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case AJGE: /* no reference */
|
||||
case AJNE:
|
||||
case AJLE:
|
||||
case AJEQ:
|
||||
case AJHI:
|
||||
case AJLS:
|
||||
case AJMI:
|
||||
case AJPL:
|
||||
case AJGT:
|
||||
case AJLT:
|
||||
case AJCC:
|
||||
case AJCS:
|
||||
|
||||
case AADJSP:
|
||||
case AWAIT:
|
||||
case ACLD:
|
||||
break;
|
||||
|
||||
case AIMULL:
|
||||
case AIMULW:
|
||||
if(p->to.type != D_NONE) {
|
||||
if(copyas(&p->to, v))
|
||||
return 2;
|
||||
goto caseread;
|
||||
}
|
||||
|
||||
case ADIVB:
|
||||
case ADIVL:
|
||||
case ADIVW:
|
||||
case AIDIVB:
|
||||
case AIDIVL:
|
||||
case AIDIVW:
|
||||
case AIMULB:
|
||||
case AMULB:
|
||||
case AMULL:
|
||||
case AMULW:
|
||||
|
||||
case ACWD:
|
||||
case ACDQ:
|
||||
if(v->type == D_AX || v->type == D_DX)
|
||||
return 2;
|
||||
goto caseread;
|
||||
|
||||
case AREP:
|
||||
case AREPN:
|
||||
if(v->type == D_CX)
|
||||
return 2;
|
||||
goto caseread;
|
||||
|
||||
case AMOVSB:
|
||||
case AMOVSL:
|
||||
if(v->type == D_DI || v->type == D_SI)
|
||||
return 2;
|
||||
goto caseread;
|
||||
|
||||
case ASTOSB:
|
||||
case ASTOSL:
|
||||
if(v->type == D_AX || v->type == D_DI)
|
||||
return 2;
|
||||
goto caseread;
|
||||
|
||||
case AJMP: /* funny */
|
||||
case AJMP:
|
||||
if(s != A) {
|
||||
if(copysub(&p->to, v, s, 1))
|
||||
return 1;
|
||||
@ -887,12 +601,12 @@ copyu(Prog *p, Adr *v, Adr *s)
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
case ARET: /* funny */
|
||||
case ARET:
|
||||
if(s != A)
|
||||
return 1;
|
||||
return 3;
|
||||
|
||||
case ACALL: /* funny */
|
||||
case ACALL:
|
||||
if(REGEXT && v->type <= REGEXT && v->type > exregoffset)
|
||||
return 2;
|
||||
if(REGARG >= 0 && v->type == (uchar)REGARG)
|
||||
@ -909,11 +623,47 @@ copyu(Prog *p, Adr *v, Adr *s)
|
||||
return 4;
|
||||
return 3;
|
||||
|
||||
case ATEXT: /* funny */
|
||||
case ATEXT:
|
||||
if(REGARG >= 0 && v->type == (uchar)REGARG)
|
||||
return 3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
proginfo(&info, p);
|
||||
|
||||
if((info.reguse|info.regset) & RtoB(v->type))
|
||||
return 2;
|
||||
|
||||
if(info.flags & LeftAddr)
|
||||
if(copyas(&p->from, v))
|
||||
return 2;
|
||||
|
||||
if((info.flags & (RightRead|RightWrite)) == (RightRead|RightWrite))
|
||||
if(copyas(&p->to, v))
|
||||
return 2;
|
||||
|
||||
if(info.flags & RightWrite) {
|
||||
if(copyas(&p->to, v)) {
|
||||
if(s != A)
|
||||
return copysub(&p->from, v, s, 1);
|
||||
if(copyau(&p->from, v))
|
||||
return 4;
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
if(info.flags & (LeftAddr|LeftRead|LeftWrite|RightAddr|RightRead|RightWrite)) {
|
||||
if(s != A) {
|
||||
if(copysub(&p->from, v, s, 1))
|
||||
return 1;
|
||||
return copysub(&p->to, v, s, 1);
|
||||
}
|
||||
if(copyau(&p->from, v))
|
||||
return 1;
|
||||
if(copyau(&p->to, v))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
331
src/cmd/8g/prog.c
Normal file
331
src/cmd/8g/prog.c
Normal file
@ -0,0 +1,331 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "gg.h"
|
||||
#include "opt.h"
|
||||
|
||||
// Matches real RtoB but can be used in global initializer.
|
||||
#define RtoB(r) (1<<((r)-D_AX))
|
||||
|
||||
enum {
|
||||
AX = RtoB(D_AX),
|
||||
BX = RtoB(D_BX),
|
||||
CX = RtoB(D_CX),
|
||||
DX = RtoB(D_DX),
|
||||
DI = RtoB(D_DI),
|
||||
SI = RtoB(D_SI),
|
||||
|
||||
LeftRdwr = LeftRead | LeftWrite,
|
||||
RightRdwr = RightRead | RightWrite,
|
||||
};
|
||||
|
||||
#undef RtoB
|
||||
|
||||
// This table gives the basic information about instruction
|
||||
// generated by the compiler and processed in the optimizer.
|
||||
// See opt.h for bit definitions.
|
||||
//
|
||||
// Instructions not generated need not be listed.
|
||||
// As an exception to that rule, we typically write down all the
|
||||
// size variants of an operation even if we just use a subset.
|
||||
//
|
||||
// The table is formatted for 8-space tabs.
|
||||
static ProgInfo progtable[ALAST] = {
|
||||
[ATYPE]= {Pseudo | Skip},
|
||||
[ATEXT]= {Pseudo},
|
||||
[AFUNCDATA]= {Pseudo},
|
||||
[APCDATA]= {Pseudo},
|
||||
|
||||
// NOP is an internal no-op that also stands
|
||||
// for USED and SET annotations, not the Intel opcode.
|
||||
[ANOP]= {LeftRead | RightWrite},
|
||||
|
||||
[AADCL]= {SizeL | LeftRead | RightRdwr | SetCarry | UseCarry},
|
||||
[AADCW]= {SizeW | LeftRead | RightRdwr | SetCarry | UseCarry},
|
||||
|
||||
[AADDB]= {SizeB | LeftRead | RightRdwr | SetCarry},
|
||||
[AADDL]= {SizeL | LeftRead | RightRdwr | SetCarry},
|
||||
[AADDW]= {SizeW | LeftRead | RightRdwr | SetCarry},
|
||||
|
||||
[AADDSD]= {SizeD | LeftRead | RightRdwr},
|
||||
[AADDSS]= {SizeF | LeftRead | RightRdwr},
|
||||
|
||||
[AANDB]= {SizeB | LeftRead | RightRdwr | SetCarry},
|
||||
[AANDL]= {SizeL | LeftRead | RightRdwr | SetCarry},
|
||||
[AANDW]= {SizeW | LeftRead | RightRdwr | SetCarry},
|
||||
|
||||
[ACALL]= {RightAddr | Call | KillCarry},
|
||||
|
||||
[ACDQ]= {OK, AX, AX | DX},
|
||||
[ACWD]= {OK, AX, AX | DX},
|
||||
|
||||
[ACLD]= {OK},
|
||||
[ASTD]= {OK},
|
||||
|
||||
[ACMPB]= {SizeB | LeftRead | RightRead | SetCarry},
|
||||
[ACMPL]= {SizeL | LeftRead | RightRead | SetCarry},
|
||||
[ACMPW]= {SizeW | LeftRead | RightRead | SetCarry},
|
||||
|
||||
[ACOMISD]= {SizeD | LeftRead | RightRead | SetCarry},
|
||||
[ACOMISS]= {SizeF | LeftRead | RightRead | SetCarry},
|
||||
|
||||
[ACVTSD2SL]= {SizeL | LeftRead | RightWrite | Conv},
|
||||
[ACVTSD2SS]= {SizeF | LeftRead | RightWrite | Conv},
|
||||
[ACVTSL2SD]= {SizeD | LeftRead | RightWrite | Conv},
|
||||
[ACVTSL2SS]= {SizeF | LeftRead | RightWrite | Conv},
|
||||
[ACVTSS2SD]= {SizeD | LeftRead | RightWrite | Conv},
|
||||
[ACVTSS2SL]= {SizeL | LeftRead | RightWrite | Conv},
|
||||
[ACVTTSD2SL]= {SizeL | LeftRead | RightWrite | Conv},
|
||||
[ACVTTSS2SL]= {SizeL | LeftRead | RightWrite | Conv},
|
||||
|
||||
[ADECB]= {SizeB | RightRdwr},
|
||||
[ADECL]= {SizeL | RightRdwr},
|
||||
[ADECW]= {SizeW | RightRdwr},
|
||||
|
||||
[ADIVB]= {SizeB | LeftRead, AX, AX},
|
||||
[ADIVL]= {SizeL | LeftRead, AX|DX, AX|DX},
|
||||
[ADIVW]= {SizeW | LeftRead, AX|DX, AX|DX},
|
||||
|
||||
[ADIVSD]= {SizeD | LeftRead | RightRdwr},
|
||||
[ADIVSS]= {SizeF | LeftRead | RightRdwr},
|
||||
|
||||
[AFLDCW]= {SizeW | LeftAddr },
|
||||
[AFSTCW]= {SizeW | RightAddr },
|
||||
|
||||
[AFADDD]= {SizeD | LeftAddr | RightRdwr},
|
||||
[AFADDDP]= {SizeD | LeftAddr | RightRdwr},
|
||||
[AFADDF]= {SizeF | LeftAddr | RightRdwr},
|
||||
|
||||
[AFCOMD]= {SizeD | LeftAddr | RightRead},
|
||||
[AFCOMDP]= {SizeD | LeftAddr | RightRead},
|
||||
[AFCOMDPP]= {SizeD | LeftAddr | RightRead},
|
||||
[AFCOMF]= {SizeF | LeftAddr | RightRead},
|
||||
[AFCOMFP]= {SizeF | LeftAddr | RightRead},
|
||||
[AFUCOMIP]= {SizeF | LeftAddr | RightRead},
|
||||
|
||||
[AFCHS]= {SizeD | RightRdwr}, // also SizeF
|
||||
|
||||
[AFDIVD]= {SizeD | LeftAddr | RightRdwr},
|
||||
[AFDIVDP]= {SizeD | LeftAddr | RightRdwr},
|
||||
[AFDIVF]= {SizeF | LeftAddr | RightRdwr},
|
||||
|
||||
[AFSUBD]= {SizeD | LeftAddr | RightRdwr},
|
||||
[AFSUBDP]= {SizeD | LeftAddr | RightRdwr},
|
||||
[AFSUBF]= {SizeF | LeftAddr | RightRdwr},
|
||||
[AFSUBRD]= {SizeD | LeftAddr | RightRdwr},
|
||||
[AFSUBRDP]= {SizeD | LeftAddr | RightRdwr},
|
||||
[AFSUBRF]= {SizeF | LeftAddr | RightRdwr},
|
||||
|
||||
[AFMOVD]= {SizeD | LeftAddr | RightWrite},
|
||||
[AFMOVF]= {SizeF | LeftAddr | RightWrite},
|
||||
[AFMOVL]= {SizeL | LeftAddr | RightWrite},
|
||||
[AFMOVW]= {SizeW | LeftAddr | RightWrite},
|
||||
[AFMOVV]= {SizeQ | LeftAddr | RightWrite},
|
||||
|
||||
[AFMOVDP]= {SizeD | LeftRead | RightAddr},
|
||||
[AFMOVFP]= {SizeF | LeftRead | RightAddr},
|
||||
[AFMOVLP]= {SizeL | LeftRead | RightAddr},
|
||||
[AFMOVWP]= {SizeW | LeftRead | RightAddr},
|
||||
[AFMOVVP]= {SizeQ | LeftRead | RightAddr},
|
||||
|
||||
[AFMULD]= {SizeD | LeftAddr | RightRdwr},
|
||||
[AFMULDP]= {SizeD | LeftAddr | RightRdwr},
|
||||
[AFMULF]= {SizeF | LeftAddr | RightRdwr},
|
||||
|
||||
[AIDIVB]= {SizeB | LeftRead, AX, AX},
|
||||
[AIDIVL]= {SizeL | LeftRead, AX|DX, AX|DX},
|
||||
[AIDIVW]= {SizeW | LeftRead, AX|DX, AX|DX},
|
||||
|
||||
[AIMULB]= {SizeB | LeftRead | SetCarry, AX, AX},
|
||||
[AIMULL]= {SizeL | LeftRead | ImulAXDX | SetCarry},
|
||||
[AIMULW]= {SizeW | LeftRead | ImulAXDX | SetCarry},
|
||||
|
||||
[AINCB]= {SizeB | RightRdwr},
|
||||
[AINCL]= {SizeL | RightRdwr},
|
||||
[AINCW]= {SizeW | RightRdwr},
|
||||
|
||||
[AJCC]= {Cjmp | UseCarry},
|
||||
[AJCS]= {Cjmp | UseCarry},
|
||||
[AJEQ]= {Cjmp | UseCarry},
|
||||
[AJGE]= {Cjmp | UseCarry},
|
||||
[AJGT]= {Cjmp | UseCarry},
|
||||
[AJHI]= {Cjmp | UseCarry},
|
||||
[AJLE]= {Cjmp | UseCarry},
|
||||
[AJLS]= {Cjmp | UseCarry},
|
||||
[AJLT]= {Cjmp | UseCarry},
|
||||
[AJMI]= {Cjmp | UseCarry},
|
||||
[AJNE]= {Cjmp | UseCarry},
|
||||
[AJOC]= {Cjmp | UseCarry},
|
||||
[AJOS]= {Cjmp | UseCarry},
|
||||
[AJPC]= {Cjmp | UseCarry},
|
||||
[AJPL]= {Cjmp | UseCarry},
|
||||
[AJPS]= {Cjmp | UseCarry},
|
||||
|
||||
[AJMP]= {Jump | Break | KillCarry},
|
||||
|
||||
[ALEAL]= {LeftAddr | RightWrite},
|
||||
|
||||
[AMOVBLSX]= {SizeL | LeftRead | RightWrite | Conv},
|
||||
[AMOVBLZX]= {SizeL | LeftRead | RightWrite | Conv},
|
||||
[AMOVBWSX]= {SizeW | LeftRead | RightWrite | Conv},
|
||||
[AMOVBWZX]= {SizeW | LeftRead | RightWrite | Conv},
|
||||
[AMOVWLSX]= {SizeL | LeftRead | RightWrite | Conv},
|
||||
[AMOVWLZX]= {SizeL | LeftRead | RightWrite | Conv},
|
||||
|
||||
[AMOVB]= {SizeB | LeftRead | RightWrite | Move},
|
||||
[AMOVL]= {SizeL | LeftRead | RightWrite | Move},
|
||||
[AMOVW]= {SizeW | LeftRead | RightWrite | Move},
|
||||
|
||||
[AMOVSB]= {OK, DI|SI, DI|SI},
|
||||
[AMOVSL]= {OK, DI|SI, DI|SI},
|
||||
[AMOVSW]= {OK, DI|SI, DI|SI},
|
||||
|
||||
[AMOVSD]= {SizeD | LeftRead | RightWrite | Move},
|
||||
[AMOVSS]= {SizeF | LeftRead | RightWrite | Move},
|
||||
|
||||
// We use MOVAPD as a faster synonym for MOVSD.
|
||||
[AMOVAPD]= {SizeD | LeftRead | RightWrite | Move},
|
||||
|
||||
[AMULB]= {SizeB | LeftRead | SetCarry, AX, AX},
|
||||
[AMULL]= {SizeL | LeftRead | SetCarry, AX, AX|DX},
|
||||
[AMULW]= {SizeW | LeftRead | SetCarry, AX, AX|DX},
|
||||
|
||||
[AMULSD]= {SizeD | LeftRead | RightRdwr},
|
||||
[AMULSS]= {SizeF | LeftRead | RightRdwr},
|
||||
|
||||
[ANEGB]= {SizeB | RightRdwr | SetCarry},
|
||||
[ANEGL]= {SizeL | RightRdwr | SetCarry},
|
||||
[ANEGW]= {SizeW | RightRdwr | SetCarry},
|
||||
|
||||
[ANOTB]= {SizeB | RightRdwr},
|
||||
[ANOTL]= {SizeL | RightRdwr},
|
||||
[ANOTW]= {SizeW | RightRdwr},
|
||||
|
||||
[AORB]= {SizeB | LeftRead | RightRdwr | SetCarry},
|
||||
[AORL]= {SizeL | LeftRead | RightRdwr | SetCarry},
|
||||
[AORW]= {SizeW | LeftRead | RightRdwr | SetCarry},
|
||||
|
||||
[APOPL]= {SizeL | RightWrite},
|
||||
[APUSHL]= {SizeL | LeftRead},
|
||||
|
||||
[ARCLB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
|
||||
[ARCLL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
|
||||
[ARCLW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
|
||||
|
||||
[ARCRB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
|
||||
[ARCRL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
|
||||
[ARCRW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
|
||||
|
||||
[AREP]= {OK, CX, CX},
|
||||
[AREPN]= {OK, CX, CX},
|
||||
|
||||
[ARET]= {Break | KillCarry},
|
||||
|
||||
[AROLB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
||||
[AROLL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
||||
[AROLW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
||||
|
||||
[ARORB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
||||
[ARORL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
||||
[ARORW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
||||
|
||||
[ASALB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
||||
[ASALL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
||||
[ASALW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
||||
|
||||
[ASARB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
||||
[ASARL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
||||
[ASARW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
||||
|
||||
[ASBBB]= {SizeB | LeftRead | RightRdwr | SetCarry | UseCarry},
|
||||
[ASBBL]= {SizeL | LeftRead | RightRdwr | SetCarry | UseCarry},
|
||||
[ASBBW]= {SizeW | LeftRead | RightRdwr | SetCarry | UseCarry},
|
||||
|
||||
[ASETCC]= {SizeB | RightRdwr | UseCarry},
|
||||
[ASETCS]= {SizeB | RightRdwr | UseCarry},
|
||||
[ASETEQ]= {SizeB | RightRdwr | UseCarry},
|
||||
[ASETGE]= {SizeB | RightRdwr | UseCarry},
|
||||
[ASETGT]= {SizeB | RightRdwr | UseCarry},
|
||||
[ASETHI]= {SizeB | RightRdwr | UseCarry},
|
||||
[ASETLE]= {SizeB | RightRdwr | UseCarry},
|
||||
[ASETLS]= {SizeB | RightRdwr | UseCarry},
|
||||
[ASETLT]= {SizeB | RightRdwr | UseCarry},
|
||||
[ASETMI]= {SizeB | RightRdwr | UseCarry},
|
||||
[ASETNE]= {SizeB | RightRdwr | UseCarry},
|
||||
[ASETOC]= {SizeB | RightRdwr | UseCarry},
|
||||
[ASETOS]= {SizeB | RightRdwr | UseCarry},
|
||||
[ASETPC]= {SizeB | RightRdwr | UseCarry},
|
||||
[ASETPL]= {SizeB | RightRdwr | UseCarry},
|
||||
[ASETPS]= {SizeB | RightRdwr | UseCarry},
|
||||
|
||||
[ASHLB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
||||
[ASHLL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
||||
[ASHLW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
||||
|
||||
[ASHRB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
||||
[ASHRL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
||||
[ASHRW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
||||
|
||||
[ASTOSB]= {OK, AX|DI, DI},
|
||||
[ASTOSL]= {OK, AX|DI, DI},
|
||||
[ASTOSW]= {OK, AX|DI, DI},
|
||||
|
||||
[ASUBB]= {SizeB | LeftRead | RightRdwr | SetCarry},
|
||||
[ASUBL]= {SizeL | LeftRead | RightRdwr | SetCarry},
|
||||
[ASUBW]= {SizeW | LeftRead | RightRdwr | SetCarry},
|
||||
|
||||
[ASUBSD]= {SizeD | LeftRead | RightRdwr},
|
||||
[ASUBSS]= {SizeF | LeftRead | RightRdwr},
|
||||
|
||||
[ATESTB]= {SizeB | LeftRead | RightRead},
|
||||
[ATESTL]= {SizeL | LeftRead | RightRead},
|
||||
[ATESTW]= {SizeW | LeftRead | RightRead},
|
||||
|
||||
[AUCOMISD]= {SizeD | LeftRead | RightRead},
|
||||
[AUCOMISS]= {SizeF | LeftRead | RightRead},
|
||||
|
||||
[AUNDEF]= {OK},
|
||||
|
||||
[AUSEFIELD]= {OK},
|
||||
|
||||
[AXCHGB]= {SizeB | LeftRdwr | RightRdwr},
|
||||
[AXCHGL]= {SizeL | LeftRdwr | RightRdwr},
|
||||
[AXCHGW]= {SizeW | LeftRdwr | RightRdwr},
|
||||
|
||||
[AXORB]= {SizeB | LeftRead | RightRdwr | SetCarry},
|
||||
[AXORL]= {SizeL | LeftRead | RightRdwr | SetCarry},
|
||||
[AXORW]= {SizeW | LeftRead | RightRdwr | SetCarry},
|
||||
};
|
||||
|
||||
void
|
||||
proginfo(ProgInfo *info, Prog *p)
|
||||
{
|
||||
*info = progtable[p->as];
|
||||
if(info->flags == 0)
|
||||
fatal("unknown instruction %P", p);
|
||||
|
||||
if((info->flags & ShiftCX) && p->from.type != D_CONST)
|
||||
info->reguse |= CX;
|
||||
|
||||
if(info->flags & ImulAXDX) {
|
||||
if(p->to.type == D_NONE) {
|
||||
info->reguse |= AX;
|
||||
info->regset |= AX | DX;
|
||||
} else {
|
||||
info->flags |= RightRdwr;
|
||||
}
|
||||
}
|
||||
|
||||
// Addressing makes some registers used.
|
||||
if(p->from.type >= D_INDIR)
|
||||
info->regindex |= RtoB(p->from.type-D_INDIR);
|
||||
if(p->from.index != D_NONE)
|
||||
info->regindex |= RtoB(p->from.index);
|
||||
if(p->to.type >= D_INDIR)
|
||||
info->regindex |= RtoB(p->to.type-D_INDIR);
|
||||
if(p->to.index != D_NONE)
|
||||
info->regindex |= RtoB(p->to.index);
|
||||
}
|
317
src/cmd/8g/reg.c
317
src/cmd/8g/reg.c
@ -131,6 +131,7 @@ regopt(Prog *firstp)
|
||||
{
|
||||
Reg *r, *r1;
|
||||
Prog *p;
|
||||
ProgInfo info, info2;
|
||||
int i, z, nr;
|
||||
uint32 vreg;
|
||||
Bits bit;
|
||||
@ -190,14 +191,9 @@ regopt(Prog *firstp)
|
||||
*/
|
||||
nr = 0;
|
||||
for(p=firstp; p!=P; p=p->link) {
|
||||
switch(p->as) {
|
||||
case ADATA:
|
||||
case AGLOBL:
|
||||
case ANAME:
|
||||
case ASIGNAME:
|
||||
case ATYPE:
|
||||
proginfo(&info, p);
|
||||
if(info.flags & Skip)
|
||||
continue;
|
||||
}
|
||||
r = rega();
|
||||
nr++;
|
||||
if(firstr == R) {
|
||||
@ -214,10 +210,8 @@ regopt(Prog *firstp)
|
||||
|
||||
r1 = r->p1;
|
||||
if(r1 != R) {
|
||||
switch(r1->prog->as) {
|
||||
case ARET:
|
||||
case AJMP:
|
||||
case AIRETL:
|
||||
proginfo(&info2, r1->prog);
|
||||
if(info2.flags & Break) {
|
||||
r->p1 = R;
|
||||
r1->s1 = R;
|
||||
}
|
||||
@ -227,302 +221,31 @@ regopt(Prog *firstp)
|
||||
if(p->as == ACALL && p->to.type == D_EXTERN)
|
||||
continue;
|
||||
|
||||
// Addressing makes some registers used.
|
||||
if(p->from.type >= D_INDIR)
|
||||
r->use1.b[0] |= RtoB(p->from.type-D_INDIR);
|
||||
if(p->from.index != D_NONE)
|
||||
r->use1.b[0] |= RtoB(p->from.index);
|
||||
if(p->to.type >= D_INDIR)
|
||||
r->use2.b[0] |= RtoB(p->to.type-D_INDIR);
|
||||
if(p->to.index != D_NONE)
|
||||
r->use2.b[0] |= RtoB(p->to.index);
|
||||
r->use1.b[0] |= info.reguse | info.regindex;
|
||||
r->set.b[0] |= info.regset;
|
||||
|
||||
bit = mkvar(r, &p->from);
|
||||
if(bany(&bit))
|
||||
switch(p->as) {
|
||||
/*
|
||||
* funny
|
||||
*/
|
||||
case ALEAL:
|
||||
case AFMOVD:
|
||||
case AFMOVF:
|
||||
case AFMOVL:
|
||||
case AFMOVW:
|
||||
case AFMOVV:
|
||||
if(bany(&bit)) {
|
||||
if(info.flags & LeftAddr)
|
||||
setaddrs(bit);
|
||||
break;
|
||||
|
||||
/*
|
||||
* left side read
|
||||
*/
|
||||
default:
|
||||
if(info.flags & LeftRead)
|
||||
for(z=0; z<BITS; z++)
|
||||
r->use1.b[z] |= bit.b[z];
|
||||
break;
|
||||
|
||||
/*
|
||||
* left side read+write
|
||||
*/
|
||||
case AXCHGB:
|
||||
case AXCHGW:
|
||||
case AXCHGL:
|
||||
for(z=0; z<BITS; z++) {
|
||||
r->use1.b[z] |= bit.b[z];
|
||||
if(info.flags & LeftWrite)
|
||||
for(z=0; z<BITS; z++)
|
||||
r->set.b[z] |= bit.b[z];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
bit = mkvar(r, &p->to);
|
||||
if(bany(&bit))
|
||||
switch(p->as) {
|
||||
default:
|
||||
yyerror("reg: unknown op: %A", p->as);
|
||||
break;
|
||||
|
||||
/*
|
||||
* right side read
|
||||
*/
|
||||
case ACMPB:
|
||||
case ACMPL:
|
||||
case ACMPW:
|
||||
case ACOMISS:
|
||||
case ACOMISD:
|
||||
case AUCOMISS:
|
||||
case AUCOMISD:
|
||||
case ATESTB:
|
||||
case ATESTL:
|
||||
case ATESTW:
|
||||
for(z=0; z<BITS; z++)
|
||||
r->use2.b[z] |= bit.b[z];
|
||||
break;
|
||||
|
||||
/*
|
||||
* right side write
|
||||
*/
|
||||
case AFSTSW:
|
||||
case ALEAL:
|
||||
case ANOP:
|
||||
case AMOVL:
|
||||
case AMOVB:
|
||||
case AMOVW:
|
||||
case AMOVBLSX:
|
||||
case AMOVBLZX:
|
||||
case AMOVBWSX:
|
||||
case AMOVBWZX:
|
||||
case AMOVWLSX:
|
||||
case AMOVWLZX:
|
||||
case APOPL:
|
||||
|
||||
case AMOVSS:
|
||||
case AMOVSD:
|
||||
case ACVTSD2SL:
|
||||
case ACVTSD2SS:
|
||||
case ACVTSL2SD:
|
||||
case ACVTSL2SS:
|
||||
case ACVTSS2SD:
|
||||
case ACVTSS2SL:
|
||||
case ACVTTSD2SL:
|
||||
case ACVTTSS2SL:
|
||||
for(z=0; z<BITS; z++)
|
||||
r->set.b[z] |= bit.b[z];
|
||||
break;
|
||||
|
||||
/*
|
||||
* right side read+write
|
||||
*/
|
||||
case AINCB:
|
||||
case AINCL:
|
||||
case AINCW:
|
||||
case ADECB:
|
||||
case ADECL:
|
||||
case ADECW:
|
||||
|
||||
case AADDB:
|
||||
case AADDL:
|
||||
case AADDW:
|
||||
case AANDB:
|
||||
case AANDL:
|
||||
case AANDW:
|
||||
case ASUBB:
|
||||
case ASUBL:
|
||||
case ASUBW:
|
||||
case AORB:
|
||||
case AORL:
|
||||
case AORW:
|
||||
case AXORB:
|
||||
case AXORL:
|
||||
case AXORW:
|
||||
case ASALB:
|
||||
case ASALL:
|
||||
case ASALW:
|
||||
case ASARB:
|
||||
case ASARL:
|
||||
case ASARW:
|
||||
case ARCLB:
|
||||
case ARCLL:
|
||||
case ARCLW:
|
||||
case ARCRB:
|
||||
case ARCRL:
|
||||
case ARCRW:
|
||||
case AROLB:
|
||||
case AROLL:
|
||||
case AROLW:
|
||||
case ARORB:
|
||||
case ARORL:
|
||||
case ARORW:
|
||||
case ASHLB:
|
||||
case ASHLL:
|
||||
case ASHLW:
|
||||
case ASHRB:
|
||||
case ASHRL:
|
||||
case ASHRW:
|
||||
case AIMULL:
|
||||
case AIMULW:
|
||||
case ANEGB:
|
||||
case ANEGL:
|
||||
case ANEGW:
|
||||
case ANOTB:
|
||||
case ANOTL:
|
||||
case ANOTW:
|
||||
case AADCL:
|
||||
case ASBBL:
|
||||
|
||||
case ASETCC:
|
||||
case ASETCS:
|
||||
case ASETEQ:
|
||||
case ASETGE:
|
||||
case ASETGT:
|
||||
case ASETHI:
|
||||
case ASETLE:
|
||||
case ASETLS:
|
||||
case ASETLT:
|
||||
case ASETMI:
|
||||
case ASETNE:
|
||||
case ASETOC:
|
||||
case ASETOS:
|
||||
case ASETPC:
|
||||
case ASETPL:
|
||||
case ASETPS:
|
||||
|
||||
case AXCHGB:
|
||||
case AXCHGW:
|
||||
case AXCHGL:
|
||||
|
||||
case AADDSD:
|
||||
case AADDSS:
|
||||
case ACMPSD:
|
||||
case ACMPSS:
|
||||
case ADIVSD:
|
||||
case ADIVSS:
|
||||
case AMAXSD:
|
||||
case AMAXSS:
|
||||
case AMINSD:
|
||||
case AMINSS:
|
||||
case AMULSD:
|
||||
case AMULSS:
|
||||
case ARCPSS:
|
||||
case ARSQRTSS:
|
||||
case ASQRTSD:
|
||||
case ASQRTSS:
|
||||
case ASUBSD:
|
||||
case ASUBSS:
|
||||
case AXORPD:
|
||||
for(z=0; z<BITS; z++) {
|
||||
r->set.b[z] |= bit.b[z];
|
||||
r->use2.b[z] |= bit.b[z];
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* funny
|
||||
*/
|
||||
case AFMOVDP:
|
||||
case AFMOVFP:
|
||||
case AFMOVLP:
|
||||
case AFMOVVP:
|
||||
case AFMOVWP:
|
||||
case ACALL:
|
||||
if(bany(&bit)) {
|
||||
if(info.flags & RightAddr)
|
||||
setaddrs(bit);
|
||||
break;
|
||||
}
|
||||
|
||||
switch(p->as) {
|
||||
case AIMULL:
|
||||
case AIMULW:
|
||||
if(p->to.type != D_NONE)
|
||||
break;
|
||||
|
||||
case AIDIVL:
|
||||
case AIDIVW:
|
||||
case ADIVL:
|
||||
case ADIVW:
|
||||
case AMULL:
|
||||
case AMULW:
|
||||
r->set.b[0] |= RtoB(D_AX) | RtoB(D_DX);
|
||||
r->use1.b[0] |= RtoB(D_AX) | RtoB(D_DX);
|
||||
break;
|
||||
|
||||
case AIDIVB:
|
||||
case AIMULB:
|
||||
case ADIVB:
|
||||
case AMULB:
|
||||
r->set.b[0] |= RtoB(D_AX);
|
||||
r->use1.b[0] |= RtoB(D_AX);
|
||||
break;
|
||||
|
||||
case ACWD:
|
||||
r->set.b[0] |= RtoB(D_AX) | RtoB(D_DX);
|
||||
r->use1.b[0] |= RtoB(D_AX);
|
||||
break;
|
||||
|
||||
case ACDQ:
|
||||
r->set.b[0] |= RtoB(D_DX);
|
||||
r->use1.b[0] |= RtoB(D_AX);
|
||||
break;
|
||||
|
||||
case AREP:
|
||||
case AREPN:
|
||||
case ALOOP:
|
||||
case ALOOPEQ:
|
||||
case ALOOPNE:
|
||||
r->set.b[0] |= RtoB(D_CX);
|
||||
r->use1.b[0] |= RtoB(D_CX);
|
||||
break;
|
||||
|
||||
case AMOVSB:
|
||||
case AMOVSL:
|
||||
case AMOVSW:
|
||||
case ACMPSB:
|
||||
case ACMPSL:
|
||||
case ACMPSW:
|
||||
r->set.b[0] |= RtoB(D_SI) | RtoB(D_DI);
|
||||
r->use1.b[0] |= RtoB(D_SI) | RtoB(D_DI);
|
||||
break;
|
||||
|
||||
case ASTOSB:
|
||||
case ASTOSL:
|
||||
case ASTOSW:
|
||||
case ASCASB:
|
||||
case ASCASL:
|
||||
case ASCASW:
|
||||
r->set.b[0] |= RtoB(D_DI);
|
||||
r->use1.b[0] |= RtoB(D_AX) | RtoB(D_DI);
|
||||
break;
|
||||
|
||||
case AINSB:
|
||||
case AINSL:
|
||||
case AINSW:
|
||||
r->set.b[0] |= RtoB(D_DX) | RtoB(D_DI);
|
||||
r->use1.b[0] |= RtoB(D_DI);
|
||||
break;
|
||||
|
||||
case AOUTSB:
|
||||
case AOUTSL:
|
||||
case AOUTSW:
|
||||
r->set.b[0] |= RtoB(D_DI);
|
||||
r->use1.b[0] |= RtoB(D_DX) | RtoB(D_DI);
|
||||
break;
|
||||
if(info.flags & RightRead)
|
||||
for(z=0; z<BITS; z++)
|
||||
r->use2.b[z] |= bit.b[z];
|
||||
if(info.flags & RightWrite)
|
||||
for(z=0; z<BITS; z++)
|
||||
r->set.b[z] |= bit.b[z];
|
||||
}
|
||||
}
|
||||
if(firstr == R)
|
||||
|
Loading…
Reference in New Issue
Block a user