mirror of
https://github.com/golang/go
synced 2024-10-04 12:31:21 -06:00
999a36f9af
See golang.org/s/go12nil. This CL is about getting all the right checks inserted. A followup CL will add an optimization pass to remove redundant checks. R=ken2 CC=golang-dev https://golang.org/cl/12970043
314 lines
11 KiB
C
314 lines
11 KiB
C
// 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},
|
|
[AUNDEF]= {OK},
|
|
[AUSEFIELD]= {OK},
|
|
[ACHECKNIL]= {LeftRead},
|
|
|
|
// 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},
|
|
|
|
[AADDB]= {SizeB | LeftRead | RightRdwr | SetCarry},
|
|
[AADDL]= {SizeL | LeftRead | RightRdwr | SetCarry},
|
|
[AADDW]= {SizeW | LeftRead | RightRdwr | SetCarry},
|
|
[AADDQ]= {SizeQ | LeftRead | RightRdwr | SetCarry},
|
|
|
|
[AADDSD]= {SizeD | LeftRead | RightRdwr},
|
|
[AADDSS]= {SizeF | LeftRead | RightRdwr},
|
|
|
|
[AANDB]= {SizeB | LeftRead | RightRdwr | SetCarry},
|
|
[AANDL]= {SizeL | LeftRead | RightRdwr | SetCarry},
|
|
[AANDQ]= {SizeQ | LeftRead | RightRdwr | SetCarry},
|
|
[AANDW]= {SizeW | LeftRead | RightRdwr | SetCarry},
|
|
|
|
[ACALL]= {RightAddr | Call | KillCarry},
|
|
|
|
[ACDQ]= {OK, AX, AX | DX},
|
|
[ACQO]= {OK, AX, AX | DX},
|
|
[ACWD]= {OK, AX, AX | DX},
|
|
|
|
[ACLD]= {OK},
|
|
[ASTD]= {OK},
|
|
|
|
[ACMPB]= {SizeB | LeftRead | RightRead | SetCarry},
|
|
[ACMPL]= {SizeL | LeftRead | RightRead | SetCarry},
|
|
[ACMPQ]= {SizeQ | LeftRead | RightRead | SetCarry},
|
|
[ACMPW]= {SizeW | LeftRead | RightRead | SetCarry},
|
|
|
|
[ACOMISD]= {SizeD | LeftRead | RightRead | SetCarry},
|
|
[ACOMISS]= {SizeF | LeftRead | RightRead | SetCarry},
|
|
|
|
[ACVTSD2SL]= {SizeL | LeftRead | RightWrite | Conv},
|
|
[ACVTSD2SQ]= {SizeQ | LeftRead | RightWrite | Conv},
|
|
[ACVTSD2SS]= {SizeF | LeftRead | RightWrite | Conv},
|
|
[ACVTSL2SD]= {SizeD | LeftRead | RightWrite | Conv},
|
|
[ACVTSL2SS]= {SizeF | LeftRead | RightWrite | Conv},
|
|
[ACVTSQ2SD]= {SizeD | LeftRead | RightWrite | Conv},
|
|
[ACVTSQ2SS]= {SizeF | LeftRead | RightWrite | Conv},
|
|
[ACVTSS2SD]= {SizeD | LeftRead | RightWrite | Conv},
|
|
[ACVTSS2SL]= {SizeL | LeftRead | RightWrite | Conv},
|
|
[ACVTSS2SQ]= {SizeQ | LeftRead | RightWrite | Conv},
|
|
[ACVTTSD2SL]= {SizeL | LeftRead | RightWrite | Conv},
|
|
[ACVTTSD2SQ]= {SizeQ | LeftRead | RightWrite | Conv},
|
|
[ACVTTSS2SL]= {SizeL | LeftRead | RightWrite | Conv},
|
|
[ACVTTSS2SQ]= {SizeQ | LeftRead | RightWrite | Conv},
|
|
|
|
[ADECB]= {SizeB | RightRdwr},
|
|
[ADECL]= {SizeL | RightRdwr},
|
|
[ADECQ]= {SizeQ | RightRdwr},
|
|
[ADECW]= {SizeW | RightRdwr},
|
|
|
|
[ADIVB]= {SizeB | LeftRead | SetCarry, AX, AX},
|
|
[ADIVL]= {SizeL | LeftRead | SetCarry, AX|DX, AX|DX},
|
|
[ADIVQ]= {SizeQ | LeftRead | SetCarry, AX|DX, AX|DX},
|
|
[ADIVW]= {SizeW | LeftRead | SetCarry, AX|DX, AX|DX},
|
|
|
|
[ADIVSD]= {SizeD | LeftRead | RightRdwr},
|
|
[ADIVSS]= {SizeF | LeftRead | RightRdwr},
|
|
|
|
[AIDIVB]= {SizeB | LeftRead | SetCarry, AX, AX},
|
|
[AIDIVL]= {SizeL | LeftRead | SetCarry, AX|DX, AX|DX},
|
|
[AIDIVQ]= {SizeQ | LeftRead | SetCarry, AX|DX, AX|DX},
|
|
[AIDIVW]= {SizeW | LeftRead | SetCarry, AX|DX, AX|DX},
|
|
|
|
[AIMULB]= {SizeB | LeftRead | SetCarry, AX, AX},
|
|
[AIMULL]= {SizeL | LeftRead | ImulAXDX | SetCarry},
|
|
[AIMULQ]= {SizeQ | LeftRead | ImulAXDX | SetCarry},
|
|
[AIMULW]= {SizeW | LeftRead | ImulAXDX | SetCarry},
|
|
|
|
[AINCB]= {SizeB | RightRdwr},
|
|
[AINCL]= {SizeL | RightRdwr},
|
|
[AINCQ]= {SizeQ | 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},
|
|
|
|
[ALEAQ]= {LeftAddr | RightWrite},
|
|
|
|
[AMOVBLSX]= {SizeL | LeftRead | RightWrite | Conv},
|
|
[AMOVBLZX]= {SizeL | LeftRead | RightWrite | Conv},
|
|
[AMOVBQSX]= {SizeQ | LeftRead | RightWrite | Conv},
|
|
[AMOVBQZX]= {SizeQ | LeftRead | RightWrite | Conv},
|
|
[AMOVBWSX]= {SizeW | LeftRead | RightWrite | Conv},
|
|
[AMOVBWZX]= {SizeW | LeftRead | RightWrite | Conv},
|
|
[AMOVLQSX]= {SizeQ | LeftRead | RightWrite | Conv},
|
|
[AMOVLQZX]= {SizeQ | LeftRead | RightWrite | Conv},
|
|
[AMOVWLSX]= {SizeL | LeftRead | RightWrite | Conv},
|
|
[AMOVWLZX]= {SizeL | LeftRead | RightWrite | Conv},
|
|
[AMOVWQSX]= {SizeQ | LeftRead | RightWrite | Conv},
|
|
[AMOVWQZX]= {SizeQ | LeftRead | RightWrite | Conv},
|
|
[AMOVQL]= {SizeL | LeftRead | RightWrite | Conv},
|
|
|
|
[AMOVB]= {SizeB | LeftRead | RightWrite | Move},
|
|
[AMOVL]= {SizeL | LeftRead | RightWrite | Move},
|
|
[AMOVQ]= {SizeQ | LeftRead | RightWrite | Move},
|
|
[AMOVW]= {SizeW | LeftRead | RightWrite | Move},
|
|
|
|
[AMOVSB]= {OK, DI|SI, DI|SI},
|
|
[AMOVSL]= {OK, DI|SI, DI|SI},
|
|
[AMOVSQ]= {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},
|
|
[AMULQ]= {SizeQ | 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},
|
|
[ANEGQ]= {SizeQ | RightRdwr | SetCarry},
|
|
[ANEGW]= {SizeW | RightRdwr | SetCarry},
|
|
|
|
[ANOTB]= {SizeB | RightRdwr},
|
|
[ANOTL]= {SizeL | RightRdwr},
|
|
[ANOTQ]= {SizeQ | RightRdwr},
|
|
[ANOTW]= {SizeW | RightRdwr},
|
|
|
|
[AORB]= {SizeB | LeftRead | RightRdwr | SetCarry},
|
|
[AORL]= {SizeL | LeftRead | RightRdwr | SetCarry},
|
|
[AORQ]= {SizeQ | LeftRead | RightRdwr | SetCarry},
|
|
[AORW]= {SizeW | LeftRead | RightRdwr | SetCarry},
|
|
|
|
[APOPQ]= {SizeQ | RightWrite},
|
|
[APUSHQ]= {SizeQ | LeftRead},
|
|
|
|
[ARCLB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
|
|
[ARCLL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
|
|
[ARCLQ]= {SizeQ | 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},
|
|
[ARCRQ]= {SizeQ | 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},
|
|
[AROLQ]= {SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
[AROLW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
|
|
[ARORB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
[ARORL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
[ARORQ]= {SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
[ARORW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
|
|
[ASALB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
[ASALL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
[ASALQ]= {SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
[ASALW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
|
|
[ASARB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
[ASARL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
[ASARQ]= {SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
[ASARW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
|
|
[ASBBB]= {SizeB | LeftRead | RightRdwr | SetCarry | UseCarry},
|
|
[ASBBL]= {SizeL | LeftRead | RightRdwr | SetCarry | UseCarry},
|
|
[ASBBQ]= {SizeQ | LeftRead | RightRdwr | SetCarry | UseCarry},
|
|
[ASBBW]= {SizeW | LeftRead | RightRdwr | SetCarry | UseCarry},
|
|
|
|
[ASHLB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
[ASHLL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
[ASHLQ]= {SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
[ASHLW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
|
|
[ASHRB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
[ASHRL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
[ASHRQ]= {SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
[ASHRW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
|
|
|
|
[ASTOSB]= {OK, AX|DI, DI},
|
|
[ASTOSL]= {OK, AX|DI, DI},
|
|
[ASTOSQ]= {OK, AX|DI, DI},
|
|
[ASTOSW]= {OK, AX|DI, DI},
|
|
|
|
[ASUBB]= {SizeB | LeftRead | RightRdwr | SetCarry},
|
|
[ASUBL]= {SizeL | LeftRead | RightRdwr | SetCarry},
|
|
[ASUBQ]= {SizeQ | LeftRead | RightRdwr | SetCarry},
|
|
[ASUBW]= {SizeW | LeftRead | RightRdwr | SetCarry},
|
|
|
|
[ASUBSD]= {SizeD | LeftRead | RightRdwr},
|
|
[ASUBSS]= {SizeF | LeftRead | RightRdwr},
|
|
|
|
[ATESTB]= {SizeB | LeftRead | RightRead | SetCarry},
|
|
[ATESTL]= {SizeL | LeftRead | RightRead | SetCarry},
|
|
[ATESTQ]= {SizeQ | LeftRead | RightRead | SetCarry},
|
|
[ATESTW]= {SizeW | LeftRead | RightRead | SetCarry},
|
|
|
|
[AUCOMISD]= {SizeD | LeftRead | RightRead},
|
|
[AUCOMISS]= {SizeF | LeftRead | RightRead},
|
|
|
|
[AXCHGB]= {SizeB | LeftRdwr | RightRdwr},
|
|
[AXCHGL]= {SizeL | LeftRdwr | RightRdwr},
|
|
[AXCHGQ]= {SizeQ | LeftRdwr | RightRdwr},
|
|
[AXCHGW]= {SizeW | LeftRdwr | RightRdwr},
|
|
|
|
[AXORB]= {SizeB | LeftRead | RightRdwr | SetCarry},
|
|
[AXORL]= {SizeL | LeftRead | RightRdwr | SetCarry},
|
|
[AXORQ]= {SizeQ | 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);
|
|
}
|