github.com/zach-klippenstein/go@v0.0.0-20150108044943-fcfbeb3adf58/src/cmd/5g/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  enum
    11  {
    12  	RightRdwr = RightRead | RightWrite,
    13  };
    14  
    15  // This table gives the basic information about instruction
    16  // generated by the compiler and processed in the optimizer.
    17  // See opt.h for bit definitions.
    18  //
    19  // Instructions not generated need not be listed.
    20  // As an exception to that rule, we typically write down all the
    21  // size variants of an operation even if we just use a subset.
    22  //
    23  // The table is formatted for 8-space tabs.
    24  static ProgInfo progtable[ALAST] = {
    25  	[ATYPE]=	{Pseudo | Skip},
    26  	[ATEXT]=	{Pseudo},
    27  	[AFUNCDATA]=	{Pseudo},
    28  	[APCDATA]=	{Pseudo},
    29  	[AUNDEF]=	{Break},
    30  	[AUSEFIELD]=	{OK},
    31  	[ACHECKNIL]=	{LeftRead},
    32  	[AVARDEF]=	{Pseudo | RightWrite},
    33  	[AVARKILL]=	{Pseudo | RightWrite},
    34  
    35  	// NOP is an internal no-op that also stands
    36  	// for USED and SET annotations, not the Intel opcode.
    37  	[ANOP]=		{LeftRead | RightWrite},
    38  	
    39  	// Integer.
    40  	[AADC]=		{SizeL | LeftRead | RegRead | RightWrite},
    41  	[AADD]=		{SizeL | LeftRead | RegRead | RightWrite},
    42  	[AAND]=		{SizeL | LeftRead | RegRead | RightWrite},
    43  	[ABIC]=		{SizeL | LeftRead | RegRead | RightWrite},
    44  	[ACMN]=		{SizeL | LeftRead | RightRead},
    45  	[ACMP]=		{SizeL | LeftRead | RightRead},
    46  	[ADIVU]=	{SizeL | LeftRead | RegRead | RightWrite},
    47  	[ADIV]=		{SizeL | LeftRead | RegRead | RightWrite},
    48  	[AEOR]=		{SizeL | LeftRead | RegRead | RightWrite},
    49  	[AMODU]=	{SizeL | LeftRead | RegRead | RightWrite},
    50  	[AMOD]=		{SizeL | LeftRead | RegRead | RightWrite},
    51  	[AMULALU]=	{SizeL | LeftRead | RegRead | RightRdwr},
    52  	[AMULAL]=	{SizeL | LeftRead | RegRead | RightRdwr},
    53  	[AMULA]=	{SizeL | LeftRead | RegRead | RightRdwr},
    54  	[AMULU]=	{SizeL | LeftRead | RegRead | RightWrite},
    55  	[AMUL]=		{SizeL | LeftRead | RegRead | RightWrite},
    56  	[AMULL]=	{SizeL | LeftRead | RegRead | RightWrite},
    57  	[AMULLU]=	{SizeL | LeftRead | RegRead | RightWrite},
    58  	[AMVN]=		{SizeL | LeftRead | RightWrite},
    59  	[AORR]=		{SizeL | LeftRead | RegRead | RightWrite},
    60  	[ARSB]=		{SizeL | LeftRead | RegRead | RightWrite},
    61  	[ARSC]=		{SizeL | LeftRead | RegRead | RightWrite},
    62  	[ASBC]=		{SizeL | LeftRead | RegRead | RightWrite},
    63  	[ASLL]=		{SizeL | LeftRead | RegRead | RightWrite},
    64  	[ASRA]=		{SizeL | LeftRead | RegRead | RightWrite},
    65  	[ASRL]=		{SizeL | LeftRead | RegRead | RightWrite},
    66  	[ASUB]=		{SizeL | LeftRead | RegRead | RightWrite},
    67  	[ATEQ]=		{SizeL | LeftRead | RightRead},
    68  	[ATST]=		{SizeL | LeftRead | RightRead},
    69  
    70  	// Floating point.
    71  	[AADDD]=	{SizeD | LeftRead | RightRdwr},
    72  	[AADDF]=	{SizeF | LeftRead | RightRdwr},
    73  	[ACMPD]=	{SizeD | LeftRead | RightRead},
    74  	[ACMPF]=	{SizeF | LeftRead | RightRead},
    75  	[ADIVD]=	{SizeD | LeftRead | RightRdwr},
    76  	[ADIVF]=	{SizeF | LeftRead | RightRdwr},
    77  	[AMULD]=	{SizeD | LeftRead | RightRdwr},
    78  	[AMULF]=	{SizeF | LeftRead | RightRdwr},
    79  	[ASUBD]=	{SizeD | LeftRead | RightRdwr},
    80  	[ASUBF]=	{SizeF | LeftRead | RightRdwr},
    81  
    82  	// Conversions.
    83  	[AMOVWD]=		{SizeD | LeftRead | RightWrite | Conv},
    84  	[AMOVWF]=		{SizeF | LeftRead | RightWrite | Conv},
    85  	[AMOVDF]=		{SizeF | LeftRead | RightWrite | Conv},
    86  	[AMOVDW]=		{SizeL | LeftRead | RightWrite | Conv},
    87  	[AMOVFD]=		{SizeD | LeftRead | RightWrite | Conv},
    88  	[AMOVFW]=		{SizeL | LeftRead | RightWrite | Conv},
    89  
    90  	// Moves.
    91  	[AMOVB]=		{SizeB | LeftRead | RightWrite | Move},
    92  	[AMOVD]=		{SizeD | LeftRead | RightWrite | Move},
    93  	[AMOVF]=		{SizeF | LeftRead | RightWrite | Move},
    94  	[AMOVH]=		{SizeW | LeftRead | RightWrite | Move},
    95  	[AMOVW]=		{SizeL | LeftRead | RightWrite | Move},
    96  	// In addtion, duffzero reads R0,R1 and writes R1.  This fact is
    97  	// encoded in peep.c
    98  	[ADUFFZERO]=		{Call},
    99  	// In addtion, duffcopy reads R1,R2 and writes R0,R1,R2.  This fact is
   100  	// encoded in peep.c
   101  	[ADUFFCOPY]=		{Call},
   102  
   103  	// These should be split into the two different conversions instead
   104  	// of overloading the one.
   105  	[AMOVBS]=		{SizeB | LeftRead | RightWrite | Conv},
   106  	[AMOVBU]=		{SizeB | LeftRead | RightWrite | Conv},
   107  	[AMOVHS]=		{SizeW | LeftRead | RightWrite | Conv},
   108  	[AMOVHU]=		{SizeW | LeftRead | RightWrite | Conv},
   109  	
   110  	// Jumps.
   111  	[AB]=		{Jump | Break},
   112  	[ABL]=		{Call},
   113  	[ABEQ]=		{Cjmp},
   114  	[ABNE]=		{Cjmp},
   115  	[ABCS]=		{Cjmp},
   116  	[ABHS]=		{Cjmp},
   117  	[ABCC]=		{Cjmp},
   118  	[ABLO]=		{Cjmp},
   119  	[ABMI]=		{Cjmp},
   120  	[ABPL]=		{Cjmp},
   121  	[ABVS]=		{Cjmp},
   122  	[ABVC]=		{Cjmp},
   123  	[ABHI]=		{Cjmp},
   124  	[ABLS]=		{Cjmp},
   125  	[ABGE]=		{Cjmp},
   126  	[ABLT]=		{Cjmp},
   127  	[ABGT]=		{Cjmp},
   128  	[ABLE]=		{Cjmp},
   129  	[ARET]=		{Break},
   130  };
   131  
   132  void
   133  proginfo(ProgInfo *info, Prog *p)
   134  {
   135  	*info = progtable[p->as];
   136  	if(info->flags == 0)
   137  		fatal("unknown instruction %P", p);
   138  
   139  	if(p->from.type == D_CONST && p->from.sym != nil && (info->flags & LeftRead)) {
   140  		info->flags &= ~LeftRead;
   141  		info->flags |= LeftAddr;
   142  	}
   143  
   144  	if((info->flags & RegRead) && p->reg == NREG) {
   145  		info->flags &= ~RegRead;
   146  		info->flags |= CanRegRead | RightRead;
   147  	}
   148  	
   149  	if(((p->scond & C_SCOND) != C_SCOND_NONE) && (info->flags & RightWrite))
   150  		info->flags |= RightRead;
   151  }