summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/icode/Primitives.scala
blob: 2785f893ad13a869b2b8be654fc57a2a0d8e6d99 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/* NSC -- new scala compiler
 * Copyright 2005-2013 LAMP/EPFL
 * @author  Martin Odersky
 */


package scala.tools.nsc
package backend
package icode

trait Primitives { self: ICodes =>

  /** This class represents a test operation. */
  sealed abstract class TestOp {

    /** Returns the negation of this operation. */
    def negate(): TestOp

    /** Returns a string representation of this operation. */
    override def toString(): String

    /** used only from GenASM */
    def opcodeIF(): Int

    /** used only from GenASM */
    def opcodeIFICMP(): Int
  }

  /** An equality test */
  case object EQ extends TestOp {
    def negate() = NE
    override def toString() = "EQ"
    override def opcodeIF()     = scala.tools.asm.Opcodes.IFEQ
    override def opcodeIFICMP() = scala.tools.asm.Opcodes.IF_ICMPEQ
  }

  /** A non-equality test */
  case object NE extends TestOp {
    def negate() = EQ
    override def toString() = "NE"
    override def opcodeIF()     = scala.tools.asm.Opcodes.IFNE
    override def opcodeIFICMP() = scala.tools.asm.Opcodes.IF_ICMPNE
  }

  /** A less-than test */
  case object LT extends TestOp {
    def negate() = GE
    override def toString() = "LT"
    override def opcodeIF()     = scala.tools.asm.Opcodes.IFLT
    override def opcodeIFICMP() = scala.tools.asm.Opcodes.IF_ICMPLT
  }

  /** A greater-than-or-equal test */
  case object GE extends TestOp {
    def negate() = LT
    override def toString() = "GE"
    override def opcodeIF()     = scala.tools.asm.Opcodes.IFGE
    override def opcodeIFICMP() = scala.tools.asm.Opcodes.IF_ICMPGE
  }

  /** A less-than-or-equal test */
  case object LE extends TestOp {
    def negate() = GT
    override def toString() = "LE"
    override def opcodeIF()     = scala.tools.asm.Opcodes.IFLE
    override def opcodeIFICMP() = scala.tools.asm.Opcodes.IF_ICMPLE
  }

  /** A greater-than test */
  case object GT extends TestOp {
    def negate() = LE
    override def toString() = "GT"
    override def opcodeIF()     = scala.tools.asm.Opcodes.IFGT
    override def opcodeIFICMP() = scala.tools.asm.Opcodes.IF_ICMPGT
  }

  /** This class represents an arithmetic operation. */
  class ArithmeticOp {

    /** Returns a string representation of this operation. */
    override def toString(): String = this match {
      case ADD => "ADD"
      case SUB => "SUB"
      case MUL => "MUL"
      case DIV => "DIV"
      case REM => "REM"
      case NOT => "NOT"
      case _   => throw new RuntimeException("ArithmeticOp unknown case")
    }
  }

  /** An arithmetic addition operation */
  case object ADD extends ArithmeticOp

  /** An arithmetic subtraction operation */
  case object SUB extends ArithmeticOp

  /** An arithmetic multiplication operation */
  case object MUL extends ArithmeticOp

  /** An arithmetic division operation */
  case object DIV extends ArithmeticOp

  /** An arithmetic remainder operation */
  case object REM extends ArithmeticOp

  /** Bitwise negation. */
  case object NOT extends ArithmeticOp
}