Nearly CC
An educational compiler skeleton
operand.h
1 // Copyright (c) 2021-2023, David H. Hovemeyer <david.hovemeyer@gmail.com>
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the "Software"),
5 // to deal in the Software without restriction, including without limitation
6 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 // and/or sell copies of the Software, and to permit persons to whom the
8 // Software is furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
17 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
19 // OTHER DEALINGS IN THE SOFTWARE.
20 
21 #ifndef OPERAND_H
22 #define OPERAND_H
23 
24 #include <string>
25 
26 // Operand of an Instruction.
27 // Can be used for both high-level linear IR code and low-level
28 // (machine) linear IR code. These have value semantics, and
29 // can be passed and returned by value.
30 
31 class Operand {
32 public:
33  enum Kind {
34  NONE, // used only for invalid Operand values
35 
36  // Description Example
37  // -------------------------------- ---------------------
38 
39  // High-level operands
40  VREG, // just a vreg vr0
41  VREG_MEM, // memref using vreg ptr (vr0)
42  VREG_MEM_OFF, // memref using vreg ptr+imm offset 8(vr0)
43 
44  // Low-level operands
45  MREG8, // just an mreg %al
46  MREG16, // just an mreg %ax
47  MREG32, // just an mreg %eax
48  MREG64, // just an mreg %rax
49  MREG64_MEM, // memref using mreg ptr (%rax)
50  MREG64_MEM_IDX, // memref using mreg ptr+index (%rax,%rsi)
51  MREG64_MEM_OFF, // memref using mreg ptr+imm offset 8(%rax)
52  MREG64_MEM_IDX_SCALE, // memref mreg ptr+(index*scale) (%r13,%r9,4)
53 
54  // Immediate integer operands (used for both high-level and
55  // low-level code)
56  IMM_IVAL, // immediate signed int $1
57 
58  // Label an immediate lable operands (used for both high-level and
59  // low-level code)
60  LABEL, // label .L0
61  IMM_LABEL, // immediate label $printf
62  };
63 
64 private:
65  Kind m_kind;
66  int m_basereg, m_index_reg;
67 #ifdef SOLUTION
68  Kind m_mreg_kind;
69  int m_mreg;
70 #endif
71  long m_imm_ival; // also used for offset and scale
72  std::string m_label;
73 
74 public:
75  Operand(Kind kind = NONE);
76 
77  // ival1 is either basereg or imm_ival (depending on operand Kind)
78  Operand(Kind kind, long ival1);
79 
80  // ival2 is either index_reg or imm_ival (depending on operand kind)
81  Operand(Kind kind, int basereg, long ival2);
82 
83  // This is only used for MREG64_MEM_IDX_SCALE operands
84  Operand(Kind kind, int basereg, int indexreg, int scale);
85 
86  // for label or immediate label operands
87  Operand(Kind kind, const std::string &label);
88 
89  ~Operand();
90 
91  // use compiler-generated copy ctor and assignment op
92 
93  // compare two Operands for equality
94  bool operator==(const Operand &rhs) const;
95 
96  Kind get_kind() const;
97 #ifdef SOLUTION
98 
99  // These member functions are used by the local register allocator
100  bool has_mreg() const;
101  Kind get_mreg_kind() const;
102  int get_mreg() const;
103  void set_mreg(Kind mreg_kind, int mreg);
104 #endif
105 
106  // Is the operand an immediate integer value?
107  bool is_imm_ival() const;
108 
109  // Is the operand a non-immediate label?
110  bool is_label() const;
111 
112  // Is the operand an immediate label?
113  bool is_imm_label() const;
114 
115  // Does the operand have a base register?
116  bool has_base_reg() const { return m_basereg >= 0; }
117 
118  // Does the operand have an index register?
119  bool has_index_reg() const;
120 
121  // Does the operand have an immediate integer offset?
122  bool has_offset() const;
123 
124  // Does the operand have a scaling factor?
125  bool has_scale() const;
126 
127  // Is the operand a non-register operand? (i.e., no base or index reg)
128  bool is_non_reg() const;
129 
130  // Is the operand a memory reference?
131  bool is_memref() const;
132 
133  // Does the operand have an immediate integer value?
134  // (Either because it *is* an immediate integer value, or because
135  // it has an immediate integer offset.)
136  bool has_imm_ival() const;
137 
138  // Does the operand have a label?
139  // (Either because it is a label, or is an immediate label.)
140  bool has_label() const;
141 
142  // getters
143  int get_base_reg() const;
144  int get_index_reg() const;
145  long get_imm_ival() const;
146  long get_offset() const;
147  long get_scale() const;
148 
149  // setters
150  void set_base_reg(int regnum);
151  void set_index_reg(int regnum);
152  void set_imm_ival(long ival);
153  void set_offset(long offset);
154 
155  Operand to_memref() const;
156 
157  std::string get_label() const;
158 };
159 
160 #endif // OPERAND_H
Definition: operand.h:31