github.com/bgentry/go@v0.0.0-20150121062915-6cf5a733d54d/src/cmd/8g/prog.c (about)

     1  // Copyright 2013 The Go Authors.  All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  #include <u.h>
     6  #include <libc.h>
     7  #include "gg.h"
     8  #include "opt.h"
     9  
    10  // Matches real RtoB but can be used in global initializer.
    11  #define RtoB(r) (1<<((r)-D_AX))
    12  
    13  enum {
    14  	AX = RtoB(D_AX),
    15  	BX = RtoB(D_BX),
    16  	CX = RtoB(D_CX),
    17  	DX = RtoB(D_DX),
    18  	DI = RtoB(D_DI),
    19  	SI = RtoB(D_SI),
    20  	
    21  	LeftRdwr = LeftRead | LeftWrite,
    22  	RightRdwr = RightRead | RightWrite,
    23  };
    24  
    25  #undef RtoB
    26  
    27  // This table gives the basic information about instruction
    28  // generated by the compiler and processed in the optimizer.
    29  // See opt.h for bit definitions.
    30  //
    31  // Instructions not generated need not be listed.
    32  // As an exception to that rule, we typically write down all the
    33  // size variants of an operation even if we just use a subset.
    34  //
    35  // The table is formatted for 8-space tabs.
    36  static ProgInfo progtable[ALAST] = {
    37  	[ATYPE]=	{Pseudo | Skip},
    38  	[ATEXT]=	{Pseudo},
    39  	[AFUNCDATA]=	{Pseudo},
    40  	[APCDATA]=	{Pseudo},
    41  	[AUNDEF]=	{Break},
    42  	[AUSEFIELD]=	{OK},
    43  	[ACHECKNIL]=	{LeftRead},
    44  	[AVARDEF]=	{Pseudo | RightWrite},
    45  	[AVARKILL]=	{Pseudo | RightWrite},
    46  
    47  	// NOP is an internal no-op that also stands
    48  	// for USED and SET annotations, not the Intel opcode.
    49  	[ANOP]=		{LeftRead | RightWrite},
    50  
    51  	[AADCL]=	{SizeL | LeftRead | RightRdwr | SetCarry | UseCarry},
    52  	[AADCW]=	{SizeW | LeftRead | RightRdwr | SetCarry | UseCarry},
    53  
    54  	[AADDB]=	{SizeB | LeftRead | RightRdwr | SetCarry},
    55  	[AADDL]=	{SizeL | LeftRead | RightRdwr | SetCarry},
    56  	[AADDW]=	{SizeW | LeftRead | RightRdwr | SetCarry},
    57  	
    58  	[AADDSD]=	{SizeD | LeftRead | RightRdwr},
    59  	[AADDSS]=	{SizeF | LeftRead | RightRdwr},
    60  
    61  	[AANDB]=	{SizeB | LeftRead | RightRdwr | SetCarry},
    62  	[AANDL]=	{SizeL | LeftRead | RightRdwr | SetCarry},
    63  	[AANDW]=	{SizeW | LeftRead | RightRdwr | SetCarry},
    64  
    65  	[ACALL]=	{RightAddr | Call | KillCarry},
    66  
    67  	[ACDQ]=		{OK, AX, AX | DX},
    68  	[ACWD]=		{OK, AX, AX | DX},
    69  
    70  	[ACLD]=		{OK},
    71  	[ASTD]=		{OK},
    72  
    73  	[ACMPB]=	{SizeB | LeftRead | RightRead | SetCarry},
    74  	[ACMPL]=	{SizeL | LeftRead | RightRead | SetCarry},
    75  	[ACMPW]=	{SizeW | LeftRead | RightRead | SetCarry},
    76  
    77  	[ACOMISD]=	{SizeD | LeftRead | RightRead | SetCarry},
    78  	[ACOMISS]=	{SizeF | LeftRead | RightRead | SetCarry},
    79  
    80  	[ACVTSD2SL]=	{SizeL | LeftRead | RightWrite | Conv},
    81  	[ACVTSD2SS]=	{SizeF | LeftRead | RightWrite | Conv},
    82  	[ACVTSL2SD]=	{SizeD | LeftRead | RightWrite | Conv},
    83  	[ACVTSL2SS]=	{SizeF | LeftRead | RightWrite | Conv},
    84  	[ACVTSS2SD]=	{SizeD | LeftRead | RightWrite | Conv},
    85  	[ACVTSS2SL]=	{SizeL | LeftRead | RightWrite | Conv},
    86  	[ACVTTSD2SL]=	{SizeL | LeftRead | RightWrite | Conv},
    87  	[ACVTTSS2SL]=	{SizeL | LeftRead | RightWrite | Conv},
    88  
    89  	[ADECB]=	{SizeB | RightRdwr},
    90  	[ADECL]=	{SizeL | RightRdwr},
    91  	[ADECW]=	{SizeW | RightRdwr},
    92  
    93  	[ADIVB]=	{SizeB | LeftRead | SetCarry, AX, AX},
    94  	[ADIVL]=	{SizeL | LeftRead | SetCarry, AX|DX, AX|DX},
    95  	[ADIVW]=	{SizeW | LeftRead | SetCarry, AX|DX, AX|DX},
    96  
    97  	[ADIVSD]=	{SizeD | LeftRead | RightRdwr},
    98  	[ADIVSS]=	{SizeF | LeftRead | RightRdwr},
    99  	
   100  	[AFLDCW]=	{SizeW | LeftAddr},
   101  	[AFSTCW]=	{SizeW | RightAddr},
   102  
   103  	[AFSTSW]=	{SizeW | RightAddr | RightWrite},
   104  
   105  	[AFADDD]=	{SizeD | LeftAddr | RightRdwr},
   106  	[AFADDDP]=	{SizeD | LeftAddr | RightRdwr},
   107  	[AFADDF]=	{SizeF | LeftAddr | RightRdwr},
   108  
   109  	[AFCOMD]=	{SizeD | LeftAddr | RightRead},
   110  	[AFCOMDP]=	{SizeD | LeftAddr | RightRead},
   111  	[AFCOMDPP]=	{SizeD | LeftAddr | RightRead},
   112  	[AFCOMF]=	{SizeF | LeftAddr | RightRead},
   113  	[AFCOMFP]=	{SizeF | LeftAddr | RightRead},
   114  	[AFUCOMIP]=	{SizeF | LeftAddr | RightRead},
   115  
   116  	[AFCHS]=	{SizeD | RightRdwr}, // also SizeF
   117  
   118  	[AFDIVDP]=	{SizeD | LeftAddr | RightRdwr},
   119  	[AFDIVF]=	{SizeF | LeftAddr | RightRdwr},
   120  	[AFDIVD]=	{SizeD | LeftAddr | RightRdwr},
   121  
   122  	[AFDIVRDP]=	{SizeD | LeftAddr | RightRdwr},
   123  	[AFDIVRF]=	{SizeF | LeftAddr | RightRdwr},
   124  	[AFDIVRD]=	{SizeD | LeftAddr | RightRdwr},
   125  
   126  	[AFXCHD]=	{SizeD | LeftRdwr | RightRdwr},
   127  
   128  	[AFSUBD]=	{SizeD | LeftAddr | RightRdwr},
   129  	[AFSUBDP]=	{SizeD | LeftAddr | RightRdwr},
   130  	[AFSUBF]=	{SizeF | LeftAddr | RightRdwr},
   131  	[AFSUBRD]=	{SizeD | LeftAddr | RightRdwr},
   132  	[AFSUBRDP]=	{SizeD | LeftAddr | RightRdwr},
   133  	[AFSUBRF]=	{SizeF | LeftAddr | RightRdwr},
   134  
   135  	[AFMOVD]=	{SizeD | LeftAddr | RightWrite},
   136  	[AFMOVF]=	{SizeF | LeftAddr | RightWrite},
   137  	[AFMOVL]=	{SizeL | LeftAddr | RightWrite},
   138  	[AFMOVW]=	{SizeW | LeftAddr | RightWrite},
   139  	[AFMOVV]=	{SizeQ | LeftAddr | RightWrite},
   140  
   141  	// These instructions are marked as RightAddr
   142  	// so that the register optimizer does not try to replace the
   143  	// memory references with integer register references.
   144  	// But they do not use the previous value at the address, so
   145  	// we also mark them RightWrite.
   146  	[AFMOVDP]=	{SizeD | LeftRead | RightWrite | RightAddr},
   147  	[AFMOVFP]=	{SizeF | LeftRead | RightWrite | RightAddr},
   148  	[AFMOVLP]=	{SizeL | LeftRead | RightWrite | RightAddr},
   149  	[AFMOVWP]=	{SizeW | LeftRead | RightWrite | RightAddr},
   150  	[AFMOVVP]=	{SizeQ | LeftRead | RightWrite | RightAddr},
   151  
   152  	[AFMULD]=	{SizeD | LeftAddr | RightRdwr},
   153  	[AFMULDP]=	{SizeD | LeftAddr | RightRdwr},
   154  	[AFMULF]=	{SizeF | LeftAddr | RightRdwr},
   155  
   156  	[AIDIVB]=	{SizeB | LeftRead | SetCarry, AX, AX},
   157  	[AIDIVL]=	{SizeL | LeftRead | SetCarry, AX|DX, AX|DX},
   158  	[AIDIVW]=	{SizeW | LeftRead | SetCarry, AX|DX, AX|DX},
   159  
   160  	[AIMULB]=	{SizeB | LeftRead | SetCarry, AX, AX},
   161  	[AIMULL]=	{SizeL | LeftRead | ImulAXDX | SetCarry},
   162  	[AIMULW]=	{SizeW | LeftRead | ImulAXDX | SetCarry},
   163  
   164  	[AINCB]=	{SizeB | RightRdwr},
   165  	[AINCL]=	{SizeL | RightRdwr},
   166  	[AINCW]=	{SizeW | RightRdwr},
   167  
   168  	[AJCC]=		{Cjmp | UseCarry},
   169  	[AJCS]=		{Cjmp | UseCarry},
   170  	[AJEQ]=		{Cjmp | UseCarry},
   171  	[AJGE]=		{Cjmp | UseCarry},
   172  	[AJGT]=		{Cjmp | UseCarry},
   173  	[AJHI]=		{Cjmp | UseCarry},
   174  	[AJLE]=		{Cjmp | UseCarry},
   175  	[AJLS]=		{Cjmp | UseCarry},
   176  	[AJLT]=		{Cjmp | UseCarry},
   177  	[AJMI]=		{Cjmp | UseCarry},
   178  	[AJNE]=		{Cjmp | UseCarry},
   179  	[AJOC]=		{Cjmp | UseCarry},
   180  	[AJOS]=		{Cjmp | UseCarry},
   181  	[AJPC]=		{Cjmp | UseCarry},
   182  	[AJPL]=		{Cjmp | UseCarry},
   183  	[AJPS]=		{Cjmp | UseCarry},
   184  
   185  	[AJMP]=		{Jump | Break | KillCarry},
   186  
   187  	[ALEAL]=	{LeftAddr | RightWrite},
   188  
   189  	[AMOVBLSX]=	{SizeL | LeftRead | RightWrite | Conv},
   190  	[AMOVBLZX]=	{SizeL | LeftRead | RightWrite | Conv},
   191  	[AMOVBWSX]=	{SizeW | LeftRead | RightWrite | Conv},
   192  	[AMOVBWZX]=	{SizeW | LeftRead | RightWrite | Conv},
   193  	[AMOVWLSX]=	{SizeL | LeftRead | RightWrite | Conv},
   194  	[AMOVWLZX]=	{SizeL | LeftRead | RightWrite | Conv},
   195  
   196  	[AMOVB]=	{SizeB | LeftRead | RightWrite | Move},
   197  	[AMOVL]=	{SizeL | LeftRead | RightWrite | Move},
   198  	[AMOVW]=	{SizeW | LeftRead | RightWrite | Move},
   199  
   200  	[AMOVSB]=	{OK, DI|SI, DI|SI},
   201  	[AMOVSL]=	{OK, DI|SI, DI|SI},
   202  	[AMOVSW]=	{OK, DI|SI, DI|SI},
   203  	[ADUFFCOPY]=	{OK, DI|SI, DI|SI|CX},
   204  
   205  	[AMOVSD]=	{SizeD | LeftRead | RightWrite | Move},
   206  	[AMOVSS]=	{SizeF | LeftRead | RightWrite | Move},
   207  
   208  	// We use MOVAPD as a faster synonym for MOVSD.
   209  	[AMOVAPD]=	{SizeD | LeftRead | RightWrite | Move},
   210  
   211  	[AMULB]=	{SizeB | LeftRead | SetCarry, AX, AX},
   212  	[AMULL]=	{SizeL | LeftRead | SetCarry, AX, AX|DX},
   213  	[AMULW]=	{SizeW | LeftRead | SetCarry, AX, AX|DX},
   214  	
   215  	[AMULSD]=	{SizeD | LeftRead | RightRdwr},
   216  	[AMULSS]=	{SizeF | LeftRead | RightRdwr},
   217  
   218  	[ANEGB]=	{SizeB | RightRdwr | SetCarry},
   219  	[ANEGL]=	{SizeL | RightRdwr | SetCarry},
   220  	[ANEGW]=	{SizeW | RightRdwr | SetCarry},
   221  
   222  	[ANOTB]=	{SizeB | RightRdwr},
   223  	[ANOTL]=	{SizeL | RightRdwr},
   224  	[ANOTW]=	{SizeW | RightRdwr},
   225  
   226  	[AORB]=		{SizeB | LeftRead | RightRdwr | SetCarry},
   227  	[AORL]=		{SizeL | LeftRead | RightRdwr | SetCarry},
   228  	[AORW]=		{SizeW | LeftRead | RightRdwr | SetCarry},
   229  
   230  	[APOPL]=	{SizeL | RightWrite},
   231  	[APUSHL]=	{SizeL | LeftRead},
   232  
   233  	[ARCLB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
   234  	[ARCLL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
   235  	[ARCLW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
   236  
   237  	[ARCRB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
   238  	[ARCRL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
   239  	[ARCRW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
   240  
   241  	[AREP]=		{OK, CX, CX},
   242  	[AREPN]=	{OK, CX, CX},
   243  
   244  	[ARET]=		{Break | KillCarry},
   245  
   246  	[AROLB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
   247  	[AROLL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
   248  	[AROLW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
   249  
   250  	[ARORB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
   251  	[ARORL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
   252  	[ARORW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
   253  
   254  	[ASAHF]=	{OK, AX, AX},
   255  
   256  	[ASALB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
   257  	[ASALL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
   258  	[ASALW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
   259  
   260  	[ASARB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
   261  	[ASARL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
   262  	[ASARW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
   263  
   264  	[ASBBB]=	{SizeB | LeftRead | RightRdwr | SetCarry | UseCarry},
   265  	[ASBBL]=	{SizeL | LeftRead | RightRdwr | SetCarry | UseCarry},
   266  	[ASBBW]=	{SizeW | LeftRead | RightRdwr | SetCarry | UseCarry},
   267  
   268  	[ASETCC]=	{SizeB | RightRdwr | UseCarry},
   269  	[ASETCS]=	{SizeB | RightRdwr | UseCarry},
   270  	[ASETEQ]=	{SizeB | RightRdwr | UseCarry},
   271  	[ASETGE]=	{SizeB | RightRdwr | UseCarry},
   272  	[ASETGT]=	{SizeB | RightRdwr | UseCarry},
   273  	[ASETHI]=	{SizeB | RightRdwr | UseCarry},
   274  	[ASETLE]=	{SizeB | RightRdwr | UseCarry},
   275  	[ASETLS]=	{SizeB | RightRdwr | UseCarry},
   276  	[ASETLT]=	{SizeB | RightRdwr | UseCarry},
   277  	[ASETMI]=	{SizeB | RightRdwr | UseCarry},
   278  	[ASETNE]=	{SizeB | RightRdwr | UseCarry},
   279  	[ASETOC]=	{SizeB | RightRdwr | UseCarry},
   280  	[ASETOS]=	{SizeB | RightRdwr | UseCarry},
   281  	[ASETPC]=	{SizeB | RightRdwr | UseCarry},
   282  	[ASETPL]=	{SizeB | RightRdwr | UseCarry},
   283  	[ASETPS]=	{SizeB | RightRdwr | UseCarry},
   284  
   285  	[ASHLB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
   286  	[ASHLL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
   287  	[ASHLW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
   288  
   289  	[ASHRB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
   290  	[ASHRL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
   291  	[ASHRW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
   292  
   293  	[ASTOSB]=	{OK, AX|DI, DI},
   294  	[ASTOSL]=	{OK, AX|DI, DI},
   295  	[ASTOSW]=	{OK, AX|DI, DI},
   296  	[ADUFFZERO]=	{OK, AX|DI, DI},
   297  
   298  	[ASUBB]=	{SizeB | LeftRead | RightRdwr | SetCarry},
   299  	[ASUBL]=	{SizeL | LeftRead | RightRdwr | SetCarry},
   300  	[ASUBW]=	{SizeW | LeftRead | RightRdwr | SetCarry},
   301  
   302  	[ASUBSD]=	{SizeD | LeftRead | RightRdwr},
   303  	[ASUBSS]=	{SizeF | LeftRead | RightRdwr},
   304  
   305  	[ATESTB]=	{SizeB | LeftRead | RightRead | SetCarry},
   306  	[ATESTL]=	{SizeL | LeftRead | RightRead | SetCarry},
   307  	[ATESTW]=	{SizeW | LeftRead | RightRead | SetCarry},
   308  
   309  	[AUCOMISD]=	{SizeD | LeftRead | RightRead},
   310  	[AUCOMISS]=	{SizeF | LeftRead | RightRead},
   311  
   312  	[AXCHGB]=	{SizeB | LeftRdwr | RightRdwr},
   313  	[AXCHGL]=	{SizeL | LeftRdwr | RightRdwr},
   314  	[AXCHGW]=	{SizeW | LeftRdwr | RightRdwr},
   315  
   316  	[AXORB]=	{SizeB | LeftRead | RightRdwr | SetCarry},
   317  	[AXORL]=	{SizeL | LeftRead | RightRdwr | SetCarry},
   318  	[AXORW]=	{SizeW | LeftRead | RightRdwr | SetCarry},
   319  };
   320  
   321  void
   322  proginfo(ProgInfo *info, Prog *p)
   323  {
   324  	*info = progtable[p->as];
   325  	if(info->flags == 0)
   326  		fatal("unknown instruction %P", p);
   327  
   328  	if((info->flags & ShiftCX) && p->from.type != D_CONST)
   329  		info->reguse |= CX;
   330  
   331  	if(info->flags & ImulAXDX) {
   332  		if(p->to.type == D_NONE) {
   333  			info->reguse |= AX;
   334  			info->regset |= AX | DX;
   335  		} else {
   336  			info->flags |= RightRdwr;
   337  		}
   338  	}
   339  
   340  	// Addressing makes some registers used.
   341  	if(p->from.type >= D_INDIR)
   342  		info->regindex |= RtoB(p->from.type-D_INDIR);
   343  	if(p->from.index != D_NONE)
   344  		info->regindex |= RtoB(p->from.index);
   345  	if(p->to.type >= D_INDIR)
   346  		info->regindex |= RtoB(p->to.type-D_INDIR);
   347  	if(p->to.index != D_NONE)
   348  		info->regindex |= RtoB(p->to.index);
   349  }