mirror of https://github.com/golang/go.git
145 lines
4.6 KiB
C
145 lines
4.6 KiB
C
// Copyright 2014 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"
|
|
|
|
enum {
|
|
LeftRdwr = LeftRead | LeftWrite,
|
|
RightRdwr = RightRead | RightWrite,
|
|
};
|
|
|
|
// 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]= {Break},
|
|
[AUSEFIELD]= {OK},
|
|
[ACHECKNIL]= {LeftRead},
|
|
[AVARDEF]= {Pseudo | RightWrite},
|
|
[AVARKILL]= {Pseudo | RightWrite},
|
|
|
|
// NOP is an internal no-op that also stands
|
|
// for USED and SET annotations, not the Power opcode.
|
|
[ANOP]= {LeftRead | RightWrite},
|
|
|
|
// Integer
|
|
[AADD]= {SizeQ | LeftRead | RegRead | RightWrite},
|
|
[ASUB]= {SizeQ | LeftRead | RegRead | RightWrite},
|
|
[ANEG]= {SizeQ | LeftRead | RegRead | RightWrite},
|
|
[AAND]= {SizeQ | LeftRead | RegRead | RightWrite},
|
|
[AOR]= {SizeQ | LeftRead | RegRead | RightWrite},
|
|
[AXOR]= {SizeQ | LeftRead | RegRead | RightWrite},
|
|
[AMULLD]= {SizeQ | LeftRead | RegRead | RightWrite},
|
|
[AMULLW]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[AMULHD]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[AMULHDU]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[ADIVD]= {SizeQ | LeftRead | RegRead | RightWrite},
|
|
[ADIVDU]= {SizeQ | LeftRead | RegRead | RightWrite},
|
|
[ASLD]= {SizeQ | LeftRead | RegRead | RightWrite},
|
|
[ASRD]= {SizeQ | LeftRead | RegRead | RightWrite},
|
|
[ASRAD]= {SizeQ | LeftRead | RegRead | RightWrite},
|
|
[ACMP]= {SizeQ | LeftRead | RightRead},
|
|
[ACMPU]= {SizeQ | LeftRead | RightRead},
|
|
[ATD]= {SizeQ | RightRead},
|
|
|
|
// Floating point.
|
|
[AFADD]= {SizeD | LeftRead | RegRead | RightWrite},
|
|
[AFADDS]= {SizeF | LeftRead | RegRead | RightWrite},
|
|
[AFSUB]= {SizeD | LeftRead | RegRead | RightWrite},
|
|
[AFSUBS]= {SizeF | LeftRead | RegRead | RightWrite},
|
|
[AFMUL]= {SizeD | LeftRead | RegRead | RightWrite},
|
|
[AFMULS]= {SizeF | LeftRead | RegRead | RightWrite},
|
|
[AFDIV]= {SizeD | LeftRead | RegRead | RightWrite},
|
|
[AFDIVS]= {SizeF | LeftRead | RegRead | RightWrite},
|
|
[AFCTIDZ]= {SizeF | LeftRead | RegRead | RightWrite},
|
|
[AFCFID]= {SizeF | LeftRead | RegRead | RightWrite},
|
|
[AFCMPU]= {SizeD | LeftRead | RightRead},
|
|
[AFRSP]= {SizeD | LeftRead | RightWrite | Conv},
|
|
|
|
// Moves
|
|
[AMOVB]= {SizeB | LeftRead | RightWrite | Move | Conv},
|
|
[AMOVBU]= {SizeB | LeftRead | RightWrite | Move | Conv | PostInc},
|
|
[AMOVBZ]= {SizeB | LeftRead | RightWrite | Move | Conv},
|
|
[AMOVH]= {SizeW | LeftRead | RightWrite | Move | Conv},
|
|
[AMOVHU]= {SizeW | LeftRead | RightWrite | Move | Conv | PostInc},
|
|
[AMOVHZ]= {SizeW | LeftRead | RightWrite | Move | Conv},
|
|
[AMOVW]= {SizeL | LeftRead | RightWrite | Move | Conv},
|
|
// there is no AMOVWU.
|
|
[AMOVWZU]= {SizeL | LeftRead | RightWrite | Move | Conv | PostInc},
|
|
[AMOVWZ]= {SizeL | LeftRead | RightWrite | Move | Conv},
|
|
[AMOVD]= {SizeQ | LeftRead | RightWrite | Move},
|
|
[AMOVDU]= {SizeQ | LeftRead | RightWrite | Move | PostInc},
|
|
[AFMOVS]= {SizeF | LeftRead | RightWrite | Move | Conv},
|
|
[AFMOVD]= {SizeD | LeftRead | RightWrite | Move},
|
|
|
|
// Jumps
|
|
[ABR]= {Jump | Break},
|
|
[ABL]= {Call},
|
|
[ABEQ]= {Cjmp},
|
|
[ABNE]= {Cjmp},
|
|
[ABGE]= {Cjmp},
|
|
[ABLT]= {Cjmp},
|
|
[ABGT]= {Cjmp},
|
|
[ABLE]= {Cjmp},
|
|
[ARETURN]= {Break},
|
|
|
|
[ADUFFZERO]= {Call},
|
|
[ADUFFCOPY]= {Call},
|
|
};
|
|
|
|
void
|
|
proginfo(ProgInfo *info, Prog *p)
|
|
{
|
|
*info = progtable[p->as];
|
|
if(info->flags == 0) {
|
|
*info = progtable[AADD];
|
|
fatal("proginfo: unknown instruction %P", p);
|
|
}
|
|
|
|
if((info->flags & RegRead) && p->reg == NREG) {
|
|
info->flags &= ~RegRead;
|
|
info->flags |= /*CanRegRead |*/ RightRead;
|
|
}
|
|
|
|
if((p->from.type == D_OREG || p->from.type == D_CONST) && p->from.reg != NREG) {
|
|
info->regindex |= RtoB(p->from.reg);
|
|
if(info->flags & PostInc) {
|
|
info->regset |= RtoB(p->from.reg);
|
|
}
|
|
}
|
|
if((p->to.type == D_OREG || p->to.type == D_CONST) && p->to.reg != NREG) {
|
|
info->regindex |= RtoB(p->to.reg);
|
|
if(info->flags & PostInc) {
|
|
info->regset |= RtoB(p->to.reg);
|
|
}
|
|
}
|
|
|
|
if(p->from.type == D_CONST && p->from.sym != nil && (info->flags & LeftRead)) {
|
|
info->flags &= ~LeftRead;
|
|
info->flags |= LeftAddr;
|
|
}
|
|
|
|
if(p->as == ADUFFZERO) {
|
|
info->reguse |= RtoB(0) | RtoB(2);
|
|
info->regset |= RtoB(2);
|
|
}
|
|
if(p->as == ADUFFCOPY) {
|
|
info->reguse |= RtoB(0) | RtoB(2) | RtoB(3);
|
|
info->regset |= RtoB(2) | RtoB(3);
|
|
}
|
|
}
|