github.com/llir/llvm@v0.3.6/asm/inst_bitwise.go (about)

     1  package asm
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/llir/ll/ast"
     7  	"github.com/llir/llvm/ir"
     8  	"github.com/pkg/errors"
     9  )
    10  
    11  // === [ Create IR ] ===========================================================
    12  
    13  // newShlInst returns a new IR shl instruction (without body but with type)
    14  // based on the given AST shl instruction.
    15  func (fgen *funcGen) newShlInst(ident ir.LocalIdent, old *ast.ShlInst) (*ir.InstShl, error) {
    16  	typ, err := fgen.gen.irType(old.X().Typ())
    17  	if err != nil {
    18  		return nil, errors.WithStack(err)
    19  	}
    20  	return &ir.InstShl{LocalIdent: ident, Typ: typ}, nil
    21  }
    22  
    23  // newLShrInst returns a new IR lshr instruction (without body but with type)
    24  // based on the given AST lshr instruction.
    25  func (fgen *funcGen) newLShrInst(ident ir.LocalIdent, old *ast.LShrInst) (*ir.InstLShr, error) {
    26  	typ, err := fgen.gen.irType(old.X().Typ())
    27  	if err != nil {
    28  		return nil, errors.WithStack(err)
    29  	}
    30  	return &ir.InstLShr{LocalIdent: ident, Typ: typ}, nil
    31  }
    32  
    33  // newAShrInst returns a new IR ashr instruction (without body but with type)
    34  // based on the given AST ashr instruction.
    35  func (fgen *funcGen) newAShrInst(ident ir.LocalIdent, old *ast.AShrInst) (*ir.InstAShr, error) {
    36  	typ, err := fgen.gen.irType(old.X().Typ())
    37  	if err != nil {
    38  		return nil, errors.WithStack(err)
    39  	}
    40  	return &ir.InstAShr{LocalIdent: ident, Typ: typ}, nil
    41  }
    42  
    43  // newAndInst returns a new IR and instruction (without body but with type)
    44  // based on the given AST and instruction.
    45  func (fgen *funcGen) newAndInst(ident ir.LocalIdent, old *ast.AndInst) (*ir.InstAnd, error) {
    46  	typ, err := fgen.gen.irType(old.X().Typ())
    47  	if err != nil {
    48  		return nil, errors.WithStack(err)
    49  	}
    50  	return &ir.InstAnd{LocalIdent: ident, Typ: typ}, nil
    51  }
    52  
    53  // newOrInst returns a new IR or instruction (without body but with type) based
    54  // on the given AST or instruction.
    55  func (fgen *funcGen) newOrInst(ident ir.LocalIdent, old *ast.OrInst) (*ir.InstOr, error) {
    56  	typ, err := fgen.gen.irType(old.X().Typ())
    57  	if err != nil {
    58  		return nil, errors.WithStack(err)
    59  	}
    60  	return &ir.InstOr{LocalIdent: ident, Typ: typ}, nil
    61  }
    62  
    63  // newXorInst returns a new IR xor instruction (without body but with type)
    64  // based on the given AST xor instruction.
    65  func (fgen *funcGen) newXorInst(ident ir.LocalIdent, old *ast.XorInst) (*ir.InstXor, error) {
    66  	typ, err := fgen.gen.irType(old.X().Typ())
    67  	if err != nil {
    68  		return nil, errors.WithStack(err)
    69  	}
    70  	return &ir.InstXor{LocalIdent: ident, Typ: typ}, nil
    71  }
    72  
    73  // === [ Translate AST to IR ] =================================================
    74  
    75  // --- [ shl ] -----------------------------------------------------------------
    76  
    77  // irShlInst translates the given AST shl instruction into an equivalent IR
    78  // instruction.
    79  func (fgen *funcGen) irShlInst(new ir.Instruction, old *ast.ShlInst) error {
    80  	inst, ok := new.(*ir.InstShl)
    81  	if !ok {
    82  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstShl, got %T", new))
    83  	}
    84  	// X operand.
    85  	x, err := fgen.irTypeValue(old.X())
    86  	if err != nil {
    87  		return errors.WithStack(err)
    88  	}
    89  	inst.X = x
    90  	// Y operand.
    91  	y, err := fgen.irValue(x.Type(), old.Y())
    92  	if err != nil {
    93  		return errors.WithStack(err)
    94  	}
    95  	inst.Y = y
    96  	// (optional) Overflow flags.
    97  	inst.OverflowFlags = irOverflowFlags(old.OverflowFlags())
    98  	// (optional) Metadata.
    99  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   100  	if err != nil {
   101  		return errors.WithStack(err)
   102  	}
   103  	inst.Metadata = md
   104  	return nil
   105  }
   106  
   107  // --- [ lshr ] ----------------------------------------------------------------
   108  
   109  // irLShrInst translates the given AST lshr instruction into an equivalent IR
   110  // instruction.
   111  func (fgen *funcGen) irLShrInst(new ir.Instruction, old *ast.LShrInst) error {
   112  	inst, ok := new.(*ir.InstLShr)
   113  	if !ok {
   114  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstLShr, got %T", new))
   115  	}
   116  	// X operand.
   117  	x, err := fgen.irTypeValue(old.X())
   118  	if err != nil {
   119  		return errors.WithStack(err)
   120  	}
   121  	inst.X = x
   122  	// Y operand.
   123  	y, err := fgen.irValue(x.Type(), old.Y())
   124  	if err != nil {
   125  		return errors.WithStack(err)
   126  	}
   127  	inst.Y = y
   128  	// (optional) Exact.
   129  	_, inst.Exact = old.Exact()
   130  	// (optional) Metadata.
   131  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   132  	if err != nil {
   133  		return errors.WithStack(err)
   134  	}
   135  	inst.Metadata = md
   136  	return nil
   137  }
   138  
   139  // --- [ ashr ] ----------------------------------------------------------------
   140  
   141  // irAShrInst translates the given AST ashr instruction into an equivalent IR
   142  // instruction.
   143  func (fgen *funcGen) irAShrInst(new ir.Instruction, old *ast.AShrInst) error {
   144  	inst, ok := new.(*ir.InstAShr)
   145  	if !ok {
   146  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstAShr, got %T", new))
   147  	}
   148  	// X operand.
   149  	x, err := fgen.irTypeValue(old.X())
   150  	if err != nil {
   151  		return errors.WithStack(err)
   152  	}
   153  	inst.X = x
   154  	// Y operand.
   155  	y, err := fgen.irValue(x.Type(), old.Y())
   156  	if err != nil {
   157  		return errors.WithStack(err)
   158  	}
   159  	inst.Y = y
   160  	// (optional) Exact.
   161  	_, inst.Exact = old.Exact()
   162  	// (optional) Metadata.
   163  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   164  	if err != nil {
   165  		return errors.WithStack(err)
   166  	}
   167  	inst.Metadata = md
   168  	return nil
   169  }
   170  
   171  // --- [ and ] -----------------------------------------------------------------
   172  
   173  // irAndInst translates the given AST and instruction into an equivalent IR
   174  // instruction.
   175  func (fgen *funcGen) irAndInst(new ir.Instruction, old *ast.AndInst) error {
   176  	inst, ok := new.(*ir.InstAnd)
   177  	if !ok {
   178  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstAnd, got %T", new))
   179  	}
   180  	// X operand.
   181  	x, err := fgen.irTypeValue(old.X())
   182  	if err != nil {
   183  		return errors.WithStack(err)
   184  	}
   185  	inst.X = x
   186  	// Y operand.
   187  	y, err := fgen.irValue(x.Type(), old.Y())
   188  	if err != nil {
   189  		return errors.WithStack(err)
   190  	}
   191  	inst.Y = y
   192  	// (optional) Metadata.
   193  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   194  	if err != nil {
   195  		return errors.WithStack(err)
   196  	}
   197  	inst.Metadata = md
   198  	return nil
   199  }
   200  
   201  // --- [ or ] ------------------------------------------------------------------
   202  
   203  // irOrInst translates the given AST or instruction into an equivalent IR
   204  // instruction.
   205  func (fgen *funcGen) irOrInst(new ir.Instruction, old *ast.OrInst) error {
   206  	inst, ok := new.(*ir.InstOr)
   207  	if !ok {
   208  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstOr, got %T", new))
   209  	}
   210  	// X operand.
   211  	x, err := fgen.irTypeValue(old.X())
   212  	if err != nil {
   213  		return errors.WithStack(err)
   214  	}
   215  	inst.X = x
   216  	// Y operand.
   217  	y, err := fgen.irValue(x.Type(), old.Y())
   218  	if err != nil {
   219  		return errors.WithStack(err)
   220  	}
   221  	inst.Y = y
   222  	// (optional) Metadata.
   223  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   224  	if err != nil {
   225  		return errors.WithStack(err)
   226  	}
   227  	inst.Metadata = md
   228  	return nil
   229  }
   230  
   231  // --- [ xor ] -----------------------------------------------------------------
   232  
   233  // irXorInst translates the given AST xor instruction into an equivalent IR
   234  // instruction.
   235  func (fgen *funcGen) irXorInst(new ir.Instruction, old *ast.XorInst) error {
   236  	inst, ok := new.(*ir.InstXor)
   237  	if !ok {
   238  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstXor, got %T", new))
   239  	}
   240  	// X operand.
   241  	x, err := fgen.irTypeValue(old.X())
   242  	if err != nil {
   243  		return errors.WithStack(err)
   244  	}
   245  	inst.X = x
   246  	// Y operand.
   247  	y, err := fgen.irValue(x.Type(), old.Y())
   248  	if err != nil {
   249  		return errors.WithStack(err)
   250  	}
   251  	inst.Y = y
   252  	// (optional) Metadata.
   253  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   254  	if err != nil {
   255  		return errors.WithStack(err)
   256  	}
   257  	inst.Metadata = md
   258  	return nil
   259  }