modernc.org/qbe@v0.0.9/cc/literal.go (about)

     1  // Copyright 2021 The QBE 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  package cc // import "modernc.org/qbe/cc"
     6  
     7  import (
     8  	"fmt"
     9  	"math"
    10  	"math/big"
    11  
    12  	"modernc.org/cc/v3"
    13  	"modernc.org/token"
    14  )
    15  
    16  func (g *gen) intLit(n cc.Node, v cc.Value, op, from, t cc.Type) operand {
    17  	if t == nil {
    18  		panic(todo("", n.Position()))
    19  	}
    20  
    21  	switch t.Kind() {
    22  	case cc.Float, cc.Double:
    23  		return g.floatLitFromValue(n, v, from, t)
    24  	}
    25  
    26  	var u uint64
    27  	switch x := v.(type) {
    28  	case cc.Int64Value:
    29  		u = uint64(x)
    30  	case cc.Uint64Value:
    31  		u = uint64(x)
    32  	default:
    33  		panic(todo("%v: %T(%[2]v)", n.Position(), x))
    34  	}
    35  
    36  	r := g.newVal(nil)
    37  	g.w("\n%s", g.line(n))
    38  	g.w("\n\t%s =%s copy %d", r, g.baseType(n, t), u)
    39  	return r
    40  }
    41  
    42  func (g *gen) floatLitFromValue(n cc.Node, v cc.Value, from, t cc.Type) operand {
    43  	g.w("\n%s", g.line(n))
    44  	switch x := v.(type) {
    45  	case cc.Float64Value:
    46  		r := g.newVal(nil)
    47  		g.w("\n\t%s =d copy %d", r, math.Float64bits(float64(x)))
    48  		return g.convert(n, r, from, t)
    49  	case cc.Float32Value:
    50  		r := g.newVal(nil)
    51  		g.w("\n\t%s =s copy %d", r, math.Float32bits(float32(x)))
    52  		return g.convert(n, r, from, t)
    53  	case cc.Int64Value:
    54  		switch t.Kind() {
    55  		case cc.Float, cc.Double:
    56  			r := g.newVal(nil)
    57  			g.w("\n\t%s =%s sltof %d", r, g.baseType(n, t), x)
    58  			return r
    59  		default:
    60  			panic(todo("%v: %v", n.Position(), t.Kind()))
    61  		}
    62  	case *cc.Float128Value:
    63  		r := g.newVal(nil)
    64  		g.w("\n\t%s =ld copy %s", r, g.longDoubleString(n, x))
    65  		return g.convert(n, r, from, t)
    66  	default:
    67  		panic(todo("%v: %T(%[2]v)", n.Position(), x))
    68  	}
    69  }
    70  
    71  func (g *gen) longDoubleString(n cc.Node, v cc.Value) string {
    72  	switch x := v.(type) {
    73  	case *cc.Float128Value:
    74  		switch {
    75  		case x.NaN:
    76  			return "ld_nan"
    77  		case x.N.IsInf():
    78  			switch {
    79  			case x.N.Sign() > 0:
    80  				return "ld_inf"
    81  			default:
    82  				return "ld_-inf"
    83  			}
    84  		default:
    85  			m := big.NewFloat(0).SetPrec(uint(g.cLongDouble.Size()) * 8).Set(x.N)
    86  			return "ld_" + m.Text('p', 0)
    87  		}
    88  	case cc.Float64Value:
    89  		switch {
    90  		case math.IsNaN(float64(x)):
    91  			return "ld_nan"
    92  		case math.IsInf(float64(x), 1):
    93  			return "ld_inf"
    94  		case math.IsInf(float64(x), -1):
    95  			return "ld_-inf"
    96  		default:
    97  			return fmt.Sprintf("ld_%g", x)
    98  		}
    99  	case cc.Float32Value:
   100  		switch {
   101  		case math.IsNaN(float64(x)):
   102  			return "ld_nan"
   103  		case math.IsInf(float64(x), 1):
   104  			return "ld_inf"
   105  		case math.IsInf(float64(x), -1):
   106  			return "ld_-inf"
   107  		default:
   108  			return fmt.Sprintf("ld_%g", x)
   109  		}
   110  	case cc.Int64Value:
   111  		return fmt.Sprintf("ld_%v", x)
   112  	default:
   113  		panic(todo("%v: %T(%[2]v)", pos(n), x))
   114  	}
   115  }
   116  
   117  func pos(n cc.Node) (r token.Position) {
   118  	if n == nil {
   119  		return r
   120  	}
   121  
   122  	return n.Position()
   123  }
   124  
   125  func (g *gen) floatLit(n *cc.PrimaryExpression, t cc.Type) operand {
   126  	return g.floatLitFromValue(n, n.Operand.Value(), n.Operand.Type(), t)
   127  }
   128  
   129  func (g *gen) longStringLit(n cc.Node, v cc.Value) operand {
   130  	switch x := v.(type) {
   131  	case cc.WideStringValue:
   132  		s := cc.StringID(x).String()
   133  		r, ok := g.longStringLiterals[s]
   134  		if !ok {
   135  			r = g.newStaticGlobalArray()
   136  			if g.longStringLiterals == nil {
   137  				g.longStringLiterals = map[string]operand{}
   138  			}
   139  			g.longStringLiterals[s] = r
   140  		}
   141  		return r
   142  	default:
   143  		panic(todo("%v: %T", n.Position(), x))
   144  	}
   145  }
   146  
   147  func (g *gen) stringLit(n cc.Node, v cc.Value) operand {
   148  	switch x := v.(type) {
   149  	case cc.StringValue:
   150  		s := cc.StringID(x).String()
   151  		r, ok := g.stringLiterals[s]
   152  		if !ok {
   153  			r = g.newStaticGlobalArray()
   154  			if g.stringLiterals == nil {
   155  				g.stringLiterals = map[string]operand{}
   156  			}
   157  			g.stringLiterals[s] = r
   158  		}
   159  		return r
   160  	default:
   161  		panic(todo("%v: %T", n.Position(), x))
   162  	}
   163  }