modernc.org/cc@v1.0.1/v2/operand.go (about) 1 // Copyright 2017 The CC 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/cc/v2" 6 7 // [0]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf 8 9 import ( 10 "fmt" 11 "math" 12 "math/bits" 13 14 "modernc.org/ir" 15 ) 16 17 var ( 18 // [0]6.3.1.1-1 19 // 20 // Every integer type has an integer conversion rank defined as 21 // follows: 22 intConvRank = [maxTypeKind]int{ 23 Bool: 1, 24 Char: 2, 25 SChar: 2, 26 UChar: 2, 27 Short: 3, 28 UShort: 3, 29 Int: 4, 30 UInt: 4, 31 Long: 5, 32 ULong: 5, 33 LongLong: 6, 34 ULongLong: 6, 35 } 36 37 isSigned = [maxTypeKind]bool{ 38 Bool: true, 39 Char: true, 40 SChar: true, 41 Short: true, 42 Int: true, 43 Long: true, 44 LongLong: true, 45 } 46 47 isArithmeticType = [maxTypeKind]bool{ 48 Bool: true, 49 Char: true, 50 Enum: true, 51 Int: true, 52 Long: true, 53 LongLong: true, 54 SChar: true, 55 Short: true, 56 UChar: true, 57 UInt: true, 58 ULong: true, 59 ULongLong: true, 60 UShort: true, 61 62 Float: true, 63 Double: true, 64 LongDouble: true, 65 66 FloatImaginary: true, 67 DoubleImaginary: true, 68 LongDoubleImaginary: true, 69 70 FloatComplex: true, 71 DoubleComplex: true, 72 LongDoubleComplex: true, 73 } 74 ) 75 76 // Address represents the address of a variable. 77 type Address struct { //TODO- 78 Declarator *Declarator 79 Offset uintptr 80 } 81 82 func (a *Address) String() string { 83 return fmt.Sprintf("(%s+%d, %s)", dict.S(a.Declarator.Name()), a.Offset, a.Declarator.Linkage) 84 } 85 86 // UsualArithmeticConversions performs transformations of operands of a binary 87 // operation. The function panics if either of the operands is not an 88 // artithmetic type. 89 // 90 // [0]6.3.1.8 91 // 92 // Many operators that expect operands of arithmetic type cause conversions and 93 // yield result types in a similar way. The purpose is to determine a common 94 // real type for the operands and result. For the specified operands, each 95 // operand is converted, without change of type domain, to a type whose 96 // corresponding real type is the common real type. Unless explicitly stated 97 // otherwise, the common real type is also the corresponding real type of the 98 // result, whose type domain is the type domain of the operands if they are the 99 // same, and complex otherwise. This pattern is called the usual arithmetic 100 // conversions: 101 func UsualArithmeticConversions(m Model, a, b Operand) (Operand, Operand) { 102 if !a.isArithmeticType() || !b.isArithmeticType() { 103 panic(fmt.Sprint(a, b)) 104 } 105 106 a = a.normalize(m) 107 b = b.normalize(m) 108 // First, if the corresponding real type of either operand is long 109 // double, the other operand is converted, without change of type 110 // domain, to a type whose corresponding real type is long double. 111 if a.Type.Kind() == LongDoubleComplex || b.Type.Kind() == LongDoubleComplex { 112 return a.ConvertTo(m, LongDoubleComplex), b.ConvertTo(m, LongDoubleComplex) 113 } 114 115 if a.Type.Kind() == LongDouble || b.Type.Kind() == LongDouble { 116 return a.ConvertTo(m, LongDouble), b.ConvertTo(m, LongDouble) 117 } 118 119 // Otherwise, if the corresponding real type of either operand is 120 // double, the other operand is converted, without change of type 121 // domain, to a type whose corresponding real type is double. 122 if a.Type.Kind() == DoubleComplex || b.Type.Kind() == DoubleComplex { 123 return a.ConvertTo(m, DoubleComplex), b.ConvertTo(m, DoubleComplex) 124 } 125 126 if a.Type.Kind() == Double || b.Type.Kind() == Double { 127 return a.ConvertTo(m, Double), b.ConvertTo(m, Double) 128 } 129 130 // Otherwise, if the corresponding real type of either operand is 131 // float, the other operand is converted, without change of type 132 // domain, to a type whose corresponding real type is float.) 133 if a.Type.Kind() == FloatComplex || b.Type.Kind() == FloatComplex { 134 return a.ConvertTo(m, FloatComplex), b.ConvertTo(m, FloatComplex) 135 } 136 137 if a.Type.Kind() == Float || b.Type.Kind() == Float { 138 return a.ConvertTo(m, Float), b.ConvertTo(m, Float) 139 } 140 141 // Otherwise, the integer promotions are performed on both operands. 142 // Then the following rules are applied to the promoted operands: 143 if !a.isIntegerType() || !b.isIntegerType() { 144 //dbg("", a) 145 //dbg("", b) 146 panic("TODO") 147 } 148 149 a = a.integerPromotion(m) 150 b = b.integerPromotion(m) 151 152 // If both operands have the same type, then no further conversion is 153 // needed. 154 if a.Type.Equal(b.Type) { 155 return a, b 156 } 157 158 // Otherwise, if both operands have signed integer types or both have 159 // unsigned integer types, the operand with the type of lesser integer 160 // conversion rank is converted to the type of the operand with greater 161 // rank. 162 if a.isSigned() == b.isSigned() { 163 t := a.Type 164 if intConvRank[b.Type.Kind()] > intConvRank[a.Type.Kind()] { 165 t = b.Type 166 } 167 return a.ConvertTo(m, t), b.ConvertTo(m, t) 168 } 169 170 // Otherwise, if the operand that has unsigned integer type has rank 171 // greater or equal to the rank of the type of the other operand, then 172 // the operand with signed integer type is converted to the type of the 173 // operand with unsigned integer type. 174 switch { 175 case a.isSigned(): // b is unsigned 176 if intConvRank[b.Type.Kind()] >= intConvRank[a.Type.Kind()] { 177 return a.ConvertTo(m, b.Type), b 178 } 179 case b.isSigned(): // a is unsigned 180 if intConvRank[a.Type.Kind()] >= intConvRank[b.Type.Kind()] { 181 return a, b.ConvertTo(m, a.Type) 182 } 183 default: 184 panic(fmt.Errorf("TODO %v %v", a, b)) 185 } 186 187 var signed Type 188 // Otherwise, if the type of the operand with signed integer type can 189 // represent all of the values of the type of the operand with unsigned 190 // integer type, then the operand with unsigned integer type is 191 // converted to the type of the operand with signed integer type. 192 switch { 193 case a.isSigned(): // b is unsigned 194 signed = a.Type 195 if m.Sizeof(a.Type) > m.Sizeof(b.Type) { 196 return a, b.ConvertTo(m, a.Type) 197 } 198 case b.isSigned(): // a is unsigned 199 signed = b.Type 200 if m.Sizeof(b.Type) > m.Sizeof(a.Type) { 201 return a.ConvertTo(m, b.Type), b 202 } 203 default: 204 panic(fmt.Errorf("TODO %v %v", a, b)) 205 } 206 207 // Otherwise, both operands are converted to the unsigned integer type 208 // corresponding to the type of the operand with signed integer type. 209 switch signed.Kind() { 210 case Int: 211 if a.IsEnumConst || b.IsEnumConst { 212 return a, b 213 } 214 215 return a.ConvertTo(m, UInt), b.ConvertTo(m, UInt) 216 case Long: 217 return a.ConvertTo(m, ULong), b.ConvertTo(m, ULong) 218 case LongLong: 219 return a.ConvertTo(m, ULongLong), b.ConvertTo(m, ULongLong) 220 default: 221 panic(signed) 222 } 223 } 224 225 // Operand represents the type and optionally the value of an expression. 226 type Operand struct { 227 Type Type 228 ir.Value 229 FieldProperties *FieldProperties 230 231 IsEnumConst bool // Blocks int -> unsigned int promotions. See [0]6.4.4.3/2 232 } 233 234 // Bits return the width of a bit field operand or zero othewise 235 func (o *Operand) Bits() int { 236 if fp := o.FieldProperties; fp != nil { 237 return fp.Bits 238 } 239 240 return 0 241 } 242 243 func newIntConst(ctx *context, n Node, v uint64, t ...TypeKind) (r Operand) { 244 b := bits.Len64(v) 245 for _, t := range t { 246 sign := 1 247 if t.IsUnsigned() { 248 sign = 0 249 } 250 if ctx.model[t].Size*8 >= b+sign { 251 return Operand{Type: t, Value: &ir.Int64Value{Value: int64(v)}}.normalize(ctx.model) 252 } 253 } 254 255 last := t[len(t)-1] 256 if ctx.model[last].Size*8 == b { 257 return Operand{Type: last, Value: &ir.Int64Value{Value: int64(v)}}.normalize(ctx.model) 258 } 259 260 ctx.err(n, "invalid integer constant") 261 return Operand{Type: Int}.normalize(ctx.model) 262 } 263 264 func (o Operand) String() string { 265 return fmt.Sprintf("(type %v, value %v, fieldProps %+v)", o.Type, o.Value, o.FieldProperties) 266 } 267 268 func (o Operand) isArithmeticType() bool { return o.Type.IsArithmeticType() } 269 func (o Operand) isIntegerType() bool { return o.Type.IsIntegerType() } 270 func (o Operand) isPointerType() bool { return o.Type.IsPointerType() } 271 func (o Operand) isScalarType() bool { return o.Type.IsScalarType() } // [0]6.2.5-21 272 func (o Operand) isSigned() bool { return isSigned[o.Type.Kind()] } 273 274 func (o Operand) add(ctx *context, p Operand) (r Operand) { 275 o, p = UsualArithmeticConversions(ctx.model, o, p) 276 if p.IsZero() { 277 return o.normalize(ctx.model) 278 } 279 280 if o.Value == nil || p.Value == nil { 281 o.Value = nil 282 return o.normalize(ctx.model) 283 } 284 285 switch x := o.Value.(type) { 286 case *ir.Int64Value: 287 return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value + p.Value.(*ir.Int64Value).Value}}.normalize(ctx.model) 288 case *ir.Float64Value: 289 return Operand{Type: o.Type, Value: &ir.Float64Value{Value: x.Value + p.Value.(*ir.Float64Value).Value}}.normalize(ctx.model) 290 default: 291 panic(fmt.Errorf("TODO %T %v %v", x, o, p)) 292 } 293 } 294 295 func (o Operand) and(ctx *context, p Operand) (r Operand) { 296 if !o.isIntegerType() || !p.isIntegerType() { 297 panic(fmt.Errorf("TODO %v & %v", o, p)) 298 } 299 300 o, p = UsualArithmeticConversions(ctx.model, o, p) 301 if o.IsZero() || p.IsZero() { 302 return Operand{Type: o.Type, Value: &ir.Int64Value{Value: 0}}.normalize(ctx.model) 303 } 304 305 if o.Value == nil || p.Value == nil { 306 return Operand{Type: o.Type}.normalize(ctx.model) 307 } 308 309 switch x := o.Value.(type) { 310 case *ir.Int64Value: 311 return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value & p.Value.(*ir.Int64Value).Value}}.normalize(ctx.model) 312 default: 313 panic(fmt.Errorf("TODO %T", x)) 314 } 315 } 316 317 // ConvertTo converts o to type t. 318 func (o Operand) ConvertTo(m Model, t Type) (r Operand) { 319 if o.Type.Equal(t) { 320 return o.normalize(m) 321 } 322 323 switch x := t.(type) { 324 case 325 *EnumType, 326 *PointerType, 327 *TaggedEnumType, 328 *TaggedUnionType: 329 330 // ok 331 case TypeKind: 332 switch x { 333 case 334 Bool, 335 Char, 336 Double, 337 DoubleComplex, 338 DoubleImaginary, 339 Float, 340 FloatComplex, 341 FloatImaginary, 342 Int, 343 Long, 344 LongDouble, 345 LongDoubleComplex, 346 LongDoubleImaginary, 347 LongLong, 348 SChar, 349 Short, 350 UChar, 351 UInt, 352 ULong, 353 ULongLong, 354 UShort: 355 356 // ok 357 default: 358 panic(x) 359 } 360 case *NamedType: 361 return o.ConvertTo(m, x.Type) 362 default: 363 panic(fmt.Errorf("%T", x)) 364 } 365 366 if o.Value == nil { 367 o.Type = t 368 return o.normalize(m) 369 } 370 371 if o.isIntegerType() { 372 v := *o.Value.(*ir.Int64Value) 373 if t.IsIntegerType() { 374 return Operand{Type: t, Value: &v}.normalize(m) 375 } 376 377 if t.IsPointerType() { 378 // [0]6.3.2.3 379 if o.IsZero() { 380 // 3. An integer constant expression with the 381 // value 0, or such an expression cast to type 382 // void *, is called a null pointer constant. 383 // If a null pointer constant is converted to a 384 // pointer type, the resulting pointer, called 385 // a null pointer, is guaranteed to compare 386 // unequal to a pointer to any object or 387 // function. 388 return Operand{Type: t, Value: Null} 389 } 390 391 return Operand{Type: t, Value: &v}.normalize(m) 392 } 393 394 if t.Kind() == Union { 395 if v.Value != 0 { 396 panic("TODO") 397 } 398 399 return Operand{Type: t} 400 } 401 402 switch { 403 case o.Type.IsUnsigned(): 404 val := uint64(v.Value) 405 switch t.Kind() { 406 case Double, LongDouble: 407 return Operand{Type: t, Value: &ir.Float64Value{Value: float64(val)}}.normalize(m) 408 case DoubleComplex: 409 return Operand{Type: t, Value: &ir.Complex128Value{Value: complex(float64(val), 0)}}.normalize(m) 410 case Float: 411 return Operand{Type: t, Value: &ir.Float32Value{Value: float32(val)}}.normalize(m) 412 case FloatComplex: 413 return Operand{Type: t, Value: &ir.Complex64Value{Value: complex(float32(val), 0)}}.normalize(m) 414 default: 415 panic(t) 416 } 417 default: 418 val := v.Value 419 switch t.Kind() { 420 case Double, LongDouble: 421 return Operand{Type: t, Value: &ir.Float64Value{Value: float64(val)}}.normalize(m) 422 case DoubleComplex: 423 return Operand{Type: t, Value: &ir.Complex128Value{Value: complex(float64(val), 0)}}.normalize(m) 424 case Float: 425 return Operand{Type: t, Value: &ir.Float32Value{Value: float32(val)}}.normalize(m) 426 case FloatComplex: 427 return Operand{Type: t, Value: &ir.Complex64Value{Value: complex(float32(val), 0)}}.normalize(m) 428 default: 429 panic(t) 430 } 431 } 432 } 433 434 if o.Type.Kind() == Double { 435 v := o.Value.(*ir.Float64Value).Value 436 if t.IsIntegerType() { 437 return Operand{Type: t, Value: &ir.Int64Value{Value: ConvertFloat64(v, t, m)}}.normalize(m) 438 } 439 440 switch x := t.(type) { 441 case TypeKind: 442 switch x { 443 case Float: 444 return Operand{Type: t, Value: &ir.Float32Value{Value: float32(o.Value.(*ir.Float64Value).Value)}}.normalize(m) 445 case LongDouble: 446 v := *o.Value.(*ir.Float64Value) 447 return Operand{Type: t, Value: &v}.normalize(m) 448 default: 449 panic(x) 450 } 451 default: 452 panic(x) 453 } 454 } 455 456 if o.Type.Kind() == Float { 457 v := o.Value.(*ir.Float32Value).Value 458 if t.IsIntegerType() { 459 return Operand{Type: t, Value: &ir.Int64Value{Value: ConvertFloat64(float64(v), t, m)}}.normalize(m) 460 } 461 462 switch x := t.(type) { 463 case TypeKind: 464 switch x { 465 case 466 Double, 467 LongDouble: 468 469 return Operand{Type: t, Value: &ir.Float64Value{Value: float64(v)}}.normalize(m) 470 default: 471 panic(x) 472 } 473 default: 474 panic(x) 475 } 476 } 477 478 if o.isPointerType() && t.IsPointerType() { 479 o.Type = t 480 return o.normalize(m) 481 } 482 483 if o.isPointerType() && t.IsIntegerType() { 484 o.Type = t 485 switch x := o.Value.(type) { 486 case *ir.AddressValue: 487 if x.NameID != 0 { 488 o.Value = nil 489 break 490 } 491 492 o.Value = &ir.Int64Value{Value: int64(x.Offset)} 493 case 494 *ir.Int64Value, 495 *ir.StringValue: 496 497 // nop 498 default: 499 //fmt.Printf("TODO405 %T %v -> %v\n", x, o, t) //TODO- 500 panic(fmt.Errorf("%T %v -> %v", x, o, t)) 501 } 502 return o.normalize(m) 503 } 504 505 panic(fmt.Errorf("%T(%v) -> %T(%v)", o.Type, o, t, t)) 506 } 507 508 func (o Operand) cpl(ctx *context) Operand { 509 if o.isIntegerType() { 510 o = o.integerPromotion(ctx.model) 511 } 512 513 switch x := o.Value.(type) { 514 case nil: 515 return o 516 case *ir.Int64Value: 517 o.Value = &ir.Int64Value{Value: ^o.Value.(*ir.Int64Value).Value} 518 return o.normalize(ctx.model) 519 default: 520 panic(fmt.Errorf("TODO %T", x)) 521 } 522 } 523 524 func (o Operand) div(ctx *context, n Node, p Operand) (r Operand) { 525 o, p = UsualArithmeticConversions(ctx.model, o, p) 526 if o.Value == nil || p.Value == nil { 527 o.Value = nil 528 return o.normalize(ctx.model) 529 } 530 531 switch x := o.Value.(type) { 532 case *ir.Int64Value: 533 if p.IsZero() { 534 ctx.err(n, "division by zero") 535 return Operand{Type: o.Type}.normalize(ctx.model) 536 } 537 538 switch { 539 case o.Type.IsUnsigned(): 540 return Operand{Type: o.Type, Value: &ir.Int64Value{Value: int64(uint64(x.Value) / uint64(p.Value.(*ir.Int64Value).Value))}}.normalize(ctx.model) 541 default: 542 return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value / p.Value.(*ir.Int64Value).Value}}.normalize(ctx.model) 543 } 544 case *ir.Float32Value: 545 return Operand{Type: o.Type, Value: &ir.Float32Value{Value: x.Value / p.Value.(*ir.Float32Value).Value}}.normalize(ctx.model) 546 case *ir.Float64Value: 547 return Operand{Type: o.Type, Value: &ir.Float64Value{Value: x.Value / p.Value.(*ir.Float64Value).Value}}.normalize(ctx.model) 548 default: 549 panic(fmt.Errorf("TODO %T", x)) 550 } 551 } 552 553 func (o Operand) eq(ctx *context, p Operand) (r Operand) { 554 r = Operand{Type: Int} 555 if o.isArithmeticType() && p.isArithmeticType() { 556 o, p = UsualArithmeticConversions(ctx.model, o, p) 557 } 558 if o.Value == nil || p.Value == nil { 559 return r.normalize(ctx.model) 560 } 561 562 switch x := o.Value.(type) { 563 case *ir.Int64Value: 564 var val int64 565 if x.Value == p.Value.(*ir.Int64Value).Value { 566 val = 1 567 } 568 r.Value = &ir.Int64Value{Value: val} 569 case *ir.Float64Value: 570 var val int64 571 if x.Value == p.Value.(*ir.Float64Value).Value { 572 val = 1 573 } 574 r.Value = &ir.Int64Value{Value: val} 575 default: 576 panic(fmt.Errorf("TODO %T", x)) 577 } 578 return r.normalize(ctx.model) 579 } 580 581 func (o Operand) ge(ctx *context, p Operand) (r Operand) { 582 r = Operand{Type: Int} 583 if o.isArithmeticType() && p.isArithmeticType() { 584 o, p = UsualArithmeticConversions(ctx.model, o, p) 585 } 586 if o.Value == nil || p.Value == nil { 587 return r.normalize(ctx.model) 588 } 589 590 switch x := o.Value.(type) { 591 case *ir.Int64Value: 592 var val int64 593 switch { 594 case o.isSigned(): 595 if x.Value >= p.Value.(*ir.Int64Value).Value { 596 val = 1 597 } 598 default: 599 if uint64(x.Value) >= uint64(p.Value.(*ir.Int64Value).Value) { 600 val = 1 601 } 602 } 603 r.Value = &ir.Int64Value{Value: val} 604 case *ir.Float64Value: 605 var val int64 606 if x.Value >= p.Value.(*ir.Float64Value).Value { 607 val = 1 608 } 609 r.Value = &ir.Int64Value{Value: val} 610 default: 611 panic(fmt.Errorf("TODO %T", x)) 612 } 613 return r.normalize(ctx.model) 614 } 615 616 func (o Operand) gt(ctx *context, p Operand) (r Operand) { 617 r = Operand{Type: Int} 618 if o.isArithmeticType() && p.isArithmeticType() { 619 o, p = UsualArithmeticConversions(ctx.model, o, p) 620 } 621 if o.Value == nil || p.Value == nil { 622 return r.normalize(ctx.model) 623 } 624 625 switch x := o.Value.(type) { 626 case *ir.Int64Value: 627 var val int64 628 switch { 629 case o.isSigned(): 630 if x.Value > p.Value.(*ir.Int64Value).Value { 631 val = 1 632 } 633 default: 634 if uint64(x.Value) > uint64(p.Value.(*ir.Int64Value).Value) { 635 val = 1 636 } 637 } 638 r.Value = &ir.Int64Value{Value: val} 639 case *ir.Float64Value: 640 var val int64 641 if x.Value > p.Value.(*ir.Float64Value).Value { 642 val = 1 643 } 644 r.Value = &ir.Int64Value{Value: val} 645 default: 646 panic(fmt.Errorf("TODO %T", x)) 647 } 648 return r.normalize(ctx.model) 649 } 650 651 // integerPromotion computes the integer promotion of o. 652 // 653 // [0]6.3.1.1-2 654 // 655 // If an int can represent all values of the original type, the value is 656 // converted to an int; otherwise, it is converted to an unsigned int. These 657 // are called the integer promotions. All other types are unchanged by the 658 // integer promotions. 659 func (o Operand) integerPromotion(m Model) Operand { 660 t := o.Type 661 for { 662 switch x := t.(type) { 663 case *EnumType: 664 t = x.Enums[0].Operand.Type 665 case *NamedType: 666 t = x.Type 667 case *TaggedEnumType: 668 t = x.getType().(*EnumType).Enums[0].Operand.Type 669 case TypeKind: 670 // github.com/gcc-mirror/gcc/gcc/testsuite/gcc.c-torture/execute/bf-sign-2.c 671 // 672 // This test checks promotion of bitfields. Bitfields 673 // should be promoted very much like chars and shorts: 674 // 675 // Bitfields (signed or unsigned) should be promoted to 676 // signed int if their value will fit in a signed int, 677 // otherwise to an unsigned int if their value will fit 678 // in an unsigned int, otherwise we don't promote them 679 // (ANSI/ISO does not specify the behavior of bitfields 680 // larger than an unsigned int). 681 if x.IsIntegerType() && o.Bits() != 0 { 682 bits := m[Int].Size * 8 683 switch { 684 case x.IsUnsigned(): 685 if o.Bits() < bits { 686 return o.ConvertTo(m, Int) 687 } 688 default: 689 if o.Bits() < bits-1 { 690 return o.ConvertTo(m, Int) 691 } 692 } 693 } 694 695 switch x { 696 case 697 Double, 698 Float, 699 Int, 700 Long, 701 LongDouble, 702 LongLong, 703 UInt, 704 ULong, 705 ULongLong: 706 707 return o 708 case 709 Char, 710 SChar, 711 Short, 712 UChar, 713 UShort: 714 715 return o.ConvertTo(m, Int) 716 default: 717 panic(x) 718 } 719 default: 720 panic(x) 721 } 722 } 723 } 724 725 // IsNonZero returns true when the value of o is known to be non-zero. 726 func (o Operand) IsNonZero() bool { 727 switch x := o.Value.(type) { 728 case nil: 729 return false 730 case *ir.Float32Value: 731 return x.Value != 0 732 case *ir.Float64Value: 733 return x.Value != 0 734 case *ir.Int64Value: 735 return x.Value != 0 736 case *ir.StringValue: 737 return true 738 case *ir.AddressValue: 739 return x != Null 740 default: 741 panic(fmt.Errorf("TODO %T", x)) 742 } 743 } 744 745 // IsZero returns true when the value of o is known to be zero. 746 func (o Operand) IsZero() bool { 747 switch x := o.Value.(type) { 748 case nil: 749 return false 750 case *ir.Complex128Value: 751 return x.Value == 0 752 case *ir.Float32Value: 753 return x.Value == 0 754 case *ir.Float64Value: 755 return x.Value == 0 756 case *ir.Int64Value: 757 return x.Value == 0 758 case 759 *ir.StringValue, 760 *ir.WideStringValue: 761 762 return false 763 case *ir.AddressValue: 764 return x == Null 765 default: 766 panic(fmt.Errorf("TODO %T", x)) 767 } 768 } 769 770 func (o Operand) isNullPtrConst() bool { 771 return o.isIntegerType() && o.IsZero() || o.Value == Null 772 } 773 774 func (o Operand) le(ctx *context, p Operand) (r Operand) { 775 r = Operand{Type: Int} 776 if o.isArithmeticType() && p.isArithmeticType() { 777 o, p = UsualArithmeticConversions(ctx.model, o, p) 778 } 779 if o.Value == nil || p.Value == nil { 780 return r.normalize(ctx.model) 781 } 782 783 switch x := o.Value.(type) { 784 case *ir.Int64Value: 785 var val int64 786 switch { 787 case o.isSigned(): 788 if x.Value <= p.Value.(*ir.Int64Value).Value { 789 val = 1 790 } 791 default: 792 if uint64(x.Value) <= uint64(p.Value.(*ir.Int64Value).Value) { 793 val = 1 794 } 795 } 796 r.Value = &ir.Int64Value{Value: val} 797 case *ir.Float64Value: 798 var val int64 799 if x.Value <= p.Value.(*ir.Float64Value).Value { 800 val = 1 801 } 802 r.Value = &ir.Int64Value{Value: val} 803 default: 804 panic(fmt.Errorf("TODO %T", x)) 805 } 806 return r.normalize(ctx.model) 807 } 808 809 func (o Operand) lsh(ctx *context, p Operand) (r Operand) { // [0]6.5.7 810 // 2. Each of the operands shall have integer type. 811 if !o.isIntegerType() || !p.isIntegerType() { 812 panic("TODO") 813 } 814 815 // 3. The integer promotions are performed on each of the operands. The 816 // type of the result is that of the promoted left operand. If the 817 // value of the right operand is negative or is greater than or equal 818 // to the width of the promoted left operand, the behavior is 819 // undefined. 820 o = o.integerPromotion(ctx.model) 821 p = p.integerPromotion(ctx.model) 822 if o.IsZero() { 823 return o.normalize(ctx.model) 824 } 825 826 m := uint64(32) 827 if ctx.model.Sizeof(o.Type) > 4 { 828 m = 64 829 } 830 if o.Value == nil || p.Value == nil { 831 return Operand{Type: o.Type}.normalize(ctx.model) 832 } 833 834 switch x := o.Value.(type) { 835 case *ir.Int64Value: 836 return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value << (uint64(p.Value.(*ir.Int64Value).Value) % m)}}.normalize(ctx.model) 837 default: 838 panic(fmt.Errorf("TODO %T", x)) 839 } 840 } 841 842 func (o Operand) lt(ctx *context, p Operand) (r Operand) { 843 r = Operand{Type: Int} 844 if o.isArithmeticType() && p.isArithmeticType() { 845 o, p = UsualArithmeticConversions(ctx.model, o, p) 846 } 847 if o.Value == nil || p.Value == nil { 848 return r.normalize(ctx.model) 849 } 850 851 switch x := o.Value.(type) { 852 case *ir.Int64Value: 853 var val int64 854 switch { 855 case o.isSigned(): 856 if x.Value < p.Value.(*ir.Int64Value).Value { 857 val = 1 858 } 859 default: 860 if uint64(x.Value) < uint64(p.Value.(*ir.Int64Value).Value) { 861 val = 1 862 } 863 } 864 r.Value = &ir.Int64Value{Value: val} 865 case *ir.Float64Value: 866 var val int64 867 if x.Value < p.Value.(*ir.Float64Value).Value { 868 val = 1 869 } 870 r.Value = &ir.Int64Value{Value: val} 871 default: 872 panic(fmt.Errorf("TODO %T", x)) 873 } 874 return r.normalize(ctx.model) 875 } 876 877 func (o Operand) mod(ctx *context, n Node, p Operand) (r Operand) { 878 o, p = UsualArithmeticConversions(ctx.model, o, p) 879 if p.IsZero() { 880 ctx.err(n, "division by zero") 881 return p.normalize(ctx.model) 882 } 883 884 if o.IsZero() { // 0 % x == 0 885 return o.normalize(ctx.model) 886 } 887 888 if y, ok := p.Value.(*ir.Int64Value); ok && (y.Value == 1 || y.Value == -1) { 889 return Operand{Type: o.Type, Value: &ir.Int64Value{Value: 0}}.normalize(ctx.model) // y % {1,-1} == 0 890 } 891 892 if o.Value == nil || p.Value == nil { 893 return Operand{Type: o.Type}.normalize(ctx.model) 894 } 895 896 switch x := o.Value.(type) { 897 case *ir.Int64Value: 898 return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value % p.Value.(*ir.Int64Value).Value}}.normalize(ctx.model) 899 default: 900 panic(fmt.Errorf("TODO %T", x)) 901 } 902 } 903 904 func (o Operand) mul(ctx *context, p Operand) (r Operand) { 905 o, p = UsualArithmeticConversions(ctx.model, o, p) 906 if o.IsZero() || p.IsZero() { 907 switch x := UnderlyingType(o.Type).(type) { 908 case TypeKind: 909 if x.IsIntegerType() { 910 return Operand{Type: o.Type, Value: &ir.Int64Value{Value: 0}}.normalize(ctx.model) 911 } 912 default: 913 panic(fmt.Errorf("TODO %T", x)) 914 } 915 } 916 917 if o.Value == nil || p.Value == nil { 918 return Operand{Type: o.Type}.normalize(ctx.model) 919 } 920 921 switch x := o.Value.(type) { 922 case *ir.Int64Value: 923 return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value * p.Value.(*ir.Int64Value).Value}}.normalize(ctx.model) 924 case *ir.Float32Value: 925 return Operand{Type: o.Type, Value: &ir.Float32Value{Value: x.Value * p.Value.(*ir.Float32Value).Value}} 926 case *ir.Float64Value: 927 return Operand{Type: o.Type, Value: &ir.Float64Value{Value: x.Value * p.Value.(*ir.Float64Value).Value}} 928 default: 929 panic(fmt.Errorf("TODO %T", x)) 930 } 931 } 932 933 func (o Operand) ne(ctx *context, p Operand) (r Operand) { 934 r = Operand{Type: Int} 935 if o.isArithmeticType() && p.isArithmeticType() { 936 o, p = UsualArithmeticConversions(ctx.model, o, p) 937 } 938 if o.Value == nil || p.Value == nil { 939 return r.normalize(ctx.model) 940 } 941 942 switch x := o.Value.(type) { 943 case *ir.Int64Value: 944 var val int64 945 if x.Value != p.Value.(*ir.Int64Value).Value { 946 val = 1 947 } 948 r.Value = &ir.Int64Value{Value: val} 949 case *ir.Float32Value: 950 var val int64 951 if x.Value != p.Value.(*ir.Float32Value).Value { 952 val = 1 953 } 954 r.Value = &ir.Int64Value{Value: val} 955 case *ir.Float64Value: 956 var val int64 957 if x.Value != p.Value.(*ir.Float64Value).Value { 958 val = 1 959 } 960 r.Value = &ir.Int64Value{Value: val} 961 default: 962 panic(fmt.Errorf("TODO %T", x)) 963 } 964 return r.normalize(ctx.model) 965 } 966 967 // ConvertFloat64 converts v to t, which must be an integer type. 968 func ConvertFloat64(v float64, t Type, m Model) int64 { 969 if !t.IsIntegerType() { 970 panic(fmt.Errorf("ConvertFloat64: %T", t)) 971 } 972 973 switch sz := m.Sizeof(t); { 974 case t.IsUnsigned(): 975 switch sz { 976 case 1: 977 if v > math.Nextafter(math.MaxUint8, 0) { 978 return math.MaxUint8 979 } 980 981 if v <= 0 { 982 return 0 983 } 984 case 2: 985 if v > math.Nextafter(math.MaxUint16, 0) { 986 return math.MaxUint16 987 } 988 989 if v <= 0 { 990 return 0 991 } 992 case 4: 993 if v > math.Nextafter(math.MaxUint32, 0) { 994 return math.MaxUint32 995 } 996 997 if v <= 0 { 998 return 0 999 } 1000 case 8: 1001 if v > math.Nextafter(math.MaxUint64, 0) { 1002 return -1 // int64(math,MaxUint64) 1003 } 1004 1005 if v <= 0 { 1006 return 0 1007 } 1008 default: 1009 panic(sz) 1010 } 1011 default: 1012 switch sz { 1013 case 1: 1014 if v > math.Nextafter(math.MaxInt8, 0) { 1015 return math.MaxInt8 1016 } 1017 1018 if v < math.Nextafter(math.MinInt8, 0) { 1019 return math.MinInt8 1020 } 1021 case 2: 1022 if v > math.Nextafter(math.MaxInt16, 0) { 1023 return math.MaxInt16 1024 } 1025 1026 if v < math.Nextafter(math.MinInt16, 0) { 1027 return math.MinInt16 1028 } 1029 case 4: 1030 if v > math.Nextafter(math.MaxInt32, 0) { 1031 return math.MaxInt32 1032 } 1033 1034 if v < math.Nextafter(math.MinInt32, 0) { 1035 return math.MinInt32 1036 } 1037 case 8: 1038 if v > math.Nextafter(math.MaxInt64, 0) { 1039 return math.MaxInt64 1040 } 1041 1042 if v < math.Nextafter(math.MinInt64, 0) { 1043 return math.MinInt64 1044 } 1045 default: 1046 panic(sz) 1047 } 1048 } 1049 return int64(v) 1050 } 1051 1052 // ConvertInt64 converts n to t, which must be an integer or enum type, doing 1053 // masking and/or sign extending as appropriate. 1054 func ConvertInt64(n int64, t Type, m Model) int64 { 1055 switch x := UnderlyingType(t).(type) { 1056 case *EnumType: 1057 t = x.Enums[0].Operand.Type 1058 } 1059 signed := !t.IsUnsigned() 1060 switch sz := m[UnderlyingType(t).Kind()].Size; sz { 1061 case 1: 1062 switch { 1063 case signed: 1064 switch { 1065 case int8(n) < 0: 1066 return n | ^math.MaxUint8 1067 default: 1068 return n & math.MaxUint8 1069 } 1070 default: 1071 return n & math.MaxUint8 1072 } 1073 case 2: 1074 switch { 1075 case signed: 1076 switch { 1077 case int16(n) < 0: 1078 return n | ^math.MaxUint16 1079 default: 1080 return n & math.MaxUint16 1081 } 1082 default: 1083 return n & math.MaxUint16 1084 } 1085 case 4: 1086 switch { 1087 case signed: 1088 switch { 1089 case int32(n) < 0: 1090 return n | ^math.MaxUint32 1091 default: 1092 return n & math.MaxUint32 1093 } 1094 default: 1095 return n & math.MaxUint32 1096 } 1097 case 8: 1098 return n 1099 default: 1100 panic(fmt.Errorf("TODO %v %T %v", sz, t, t)) 1101 } 1102 } 1103 1104 func (o Operand) normalize(m Model) (r Operand) { 1105 switch x := o.Value.(type) { 1106 case *ir.Int64Value: 1107 if v := ConvertInt64(x.Value, o.Type, m); v != x.Value { 1108 n := *x 1109 n.Value = v 1110 x = &n 1111 o.Value = x 1112 } 1113 case nil: 1114 // nop 1115 case 1116 *ir.AddressValue, 1117 *ir.Complex128Value, 1118 *ir.Complex64Value, 1119 *ir.Float32Value, 1120 *ir.Float64Value, 1121 *ir.StringValue, 1122 *ir.WideStringValue: 1123 1124 // nop 1125 default: 1126 panic(fmt.Errorf("TODO %T", x)) 1127 } 1128 return o 1129 } 1130 1131 func (o Operand) or(ctx *context, p Operand) (r Operand) { 1132 if !o.isIntegerType() || !p.isIntegerType() { 1133 panic("TODO") 1134 } 1135 o, p = UsualArithmeticConversions(ctx.model, o, p) 1136 r.Type = o.Type 1137 if o.Value == nil || p.Value == nil { 1138 return Operand{Type: o.Type}.normalize(ctx.model) 1139 } 1140 1141 switch x := o.Value.(type) { 1142 case *ir.Int64Value: 1143 return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value | p.Value.(*ir.Int64Value).Value}}.normalize(ctx.model) 1144 default: 1145 panic(fmt.Errorf("TODO %T", x)) 1146 } 1147 } 1148 1149 func (o Operand) rsh(ctx *context, p Operand) (r Operand) { // [0]6.5.7 1150 // 2. Each of the operands shall have integer type. 1151 if !o.isIntegerType() || !p.isIntegerType() { 1152 panic("TODO") 1153 } 1154 1155 // 3. The integer promotions are performed on each of the operands. The 1156 // type of the result is that of the promoted left operand. If the 1157 // value of the right operand is negative or is greater than or equal 1158 // to the width of the promoted left operand, the behavior is 1159 // undefined. 1160 o = o.integerPromotion(ctx.model) 1161 p = p.integerPromotion(ctx.model) 1162 r.Type = o.Type 1163 m := uint64(32) 1164 if ctx.model.Sizeof(o.Type) > 4 { 1165 m = 64 1166 } 1167 if o.Value == nil || p.Value == nil { 1168 return Operand{Type: o.Type}.normalize(ctx.model) 1169 } 1170 1171 switch x := o.Value.(type) { 1172 case *ir.Int64Value: 1173 switch { 1174 case o.isSigned(): 1175 return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value >> (uint64(p.Value.(*ir.Int64Value).Value) % m)}}.normalize(ctx.model) 1176 default: 1177 return Operand{Type: o.Type, Value: &ir.Int64Value{Value: int64(uint64(x.Value) >> (uint64(p.Value.(*ir.Int64Value).Value) % m))}}.normalize(ctx.model) 1178 } 1179 default: 1180 panic(fmt.Errorf("TODO %T", x)) 1181 } 1182 } 1183 1184 func (o Operand) sub(ctx *context, p Operand) (r Operand) { 1185 o, p = UsualArithmeticConversions(ctx.model, o, p) 1186 if p.IsZero() { 1187 return o.normalize(ctx.model) 1188 } 1189 1190 if o.Value == nil || p.Value == nil { 1191 return Operand{Type: o.Type}.normalize(ctx.model) 1192 } 1193 1194 switch x := o.Value.(type) { 1195 case *ir.Int64Value: 1196 return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value - p.Value.(*ir.Int64Value).Value}}.normalize(ctx.model) 1197 case *ir.Float32Value: 1198 return Operand{Type: o.Type, Value: &ir.Float32Value{Value: x.Value - p.Value.(*ir.Float32Value).Value}}.normalize(ctx.model) 1199 case *ir.Float64Value: 1200 return Operand{Type: o.Type, Value: &ir.Float64Value{Value: x.Value - p.Value.(*ir.Float64Value).Value}}.normalize(ctx.model) 1201 default: 1202 panic(fmt.Errorf("TODO %T", x)) 1203 } 1204 } 1205 1206 func (o Operand) unaryMinus(ctx *context) Operand { 1207 if o.isIntegerType() { 1208 o = o.integerPromotion(ctx.model) 1209 } 1210 1211 switch x := o.Value.(type) { 1212 case nil: 1213 return o 1214 case *ir.Int64Value: 1215 return Operand{Type: o.Type, Value: &ir.Int64Value{Value: -x.Value}}.normalize(ctx.model) 1216 case *ir.Float32Value: 1217 return Operand{Type: o.Type, Value: &ir.Float32Value{Value: -x.Value}} 1218 case *ir.Float64Value: 1219 return Operand{Type: o.Type, Value: &ir.Float64Value{Value: -x.Value}} 1220 default: 1221 panic(fmt.Errorf("TODO %T", x)) 1222 } 1223 } 1224 1225 func (o Operand) xor(ctx *context, p Operand) (r Operand) { 1226 if !o.isIntegerType() || !p.isIntegerType() { 1227 panic("TODO") 1228 } 1229 o, p = UsualArithmeticConversions(ctx.model, o, p) 1230 if o.Value == nil || p.Value == nil { 1231 return Operand{Type: o.Type} 1232 } 1233 1234 switch x := o.Value.(type) { 1235 case *ir.Int64Value: 1236 return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value ^ p.Value.(*ir.Int64Value).Value}}.normalize(ctx.model) 1237 default: 1238 panic(fmt.Errorf("TODO %T", x)) 1239 } 1240 }