1 /* Copyright (c) 2003-2005 MySQL AB
2 Use is subject to license terms
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16
17 #ifndef NDB_INTERPRETER_HPP
18 #define NDB_INTERPRETER_HPP
19
20 #include <ndb_types.h>
21
22 class Interpreter {
23 public:
24
mod4(Uint32 len)25 inline static Uint32 mod4(Uint32 len){
26 return len + ((4 - (len & 3)) & 3);
27 }
28
29
30 /**
31 * General Mnemonic format
32 *
33 * i = Instruction - 5 Bits ( 0 - 5 ) max 63
34 * x = Register 1 - 3 Bits ( 6 - 8 ) max 7
35 * y = Register 2 - 3 Bits ( 9 -11 ) max 7
36 * b = Branch offset (only branches)
37 *
38 * 1111111111222222222233
39 * 01234567890123456789012345678901
40 * iiiiiixxxyyy bbbbbbbbbbbbbbbb
41 *
42 *
43 */
44
45 /**
46 * Instructions
47 */
48 STATIC_CONST( READ_ATTR_INTO_REG = 1 );
49 STATIC_CONST( WRITE_ATTR_FROM_REG = 2 );
50 STATIC_CONST( LOAD_CONST_NULL = 3 );
51 STATIC_CONST( LOAD_CONST16 = 4 );
52 STATIC_CONST( LOAD_CONST32 = 5 );
53 STATIC_CONST( LOAD_CONST64 = 6 );
54 STATIC_CONST( ADD_REG_REG = 7 );
55 STATIC_CONST( SUB_REG_REG = 8 );
56 STATIC_CONST( BRANCH = 9 );
57 STATIC_CONST( BRANCH_REG_EQ_NULL = 10 );
58 STATIC_CONST( BRANCH_REG_NE_NULL = 11 );
59 STATIC_CONST( BRANCH_EQ_REG_REG = 12 );
60 STATIC_CONST( BRANCH_NE_REG_REG = 13 );
61 STATIC_CONST( BRANCH_LT_REG_REG = 14 );
62 STATIC_CONST( BRANCH_LE_REG_REG = 15 );
63 STATIC_CONST( BRANCH_GT_REG_REG = 16 );
64 STATIC_CONST( BRANCH_GE_REG_REG = 17 );
65 STATIC_CONST( EXIT_OK = 18 );
66 STATIC_CONST( EXIT_REFUSE = 19 );
67 STATIC_CONST( CALL = 20 );
68 STATIC_CONST( RETURN = 21 );
69 STATIC_CONST( EXIT_OK_LAST = 22 );
70 STATIC_CONST( BRANCH_ATTR_OP_ARG = 23 );
71 STATIC_CONST( BRANCH_ATTR_EQ_NULL = 24 );
72 STATIC_CONST( BRANCH_ATTR_NE_NULL = 25 );
73
74 /**
75 * Macros for creating code
76 */
77 static Uint32 Read(Uint32 AttrId, Uint32 Register);
78 static Uint32 Write(Uint32 AttrId, Uint32 Register);
79
80 static Uint32 LoadNull(Uint32 Register);
81 static Uint32 LoadConst16(Uint32 Register, Uint32 Value);
82 static Uint32 LoadConst32(Uint32 Register); // Value in next word
83 static Uint32 LoadConst64(Uint32 Register); // Value in next 2 words
84 static Uint32 Add(Uint32 DstReg, Uint32 SrcReg1, Uint32 SrcReg2);
85 static Uint32 Sub(Uint32 DstReg, Uint32 SrcReg1, Uint32 SrcReg2);
86 static Uint32 Branch(Uint32 Inst, Uint32 Reg1, Uint32 Reg2);
87 static Uint32 ExitOK();
88
89 /**
90 * Branch string
91 *
92 * i = Instruction - 5 Bits ( 0 - 5 ) max 63
93 * a = Attribute id
94 * l = Length of string
95 * b = Branch offset
96 * t = branch type
97 * d = Array length diff
98 * v = Varchar flag
99 * p = No-blank-padding flag for char compare
100 *
101 * 1111111111222222222233
102 * 01234567890123456789012345678901
103 * iiiiii ddvtttpbbbbbbbbbbbbbbbb
104 * aaaaaaaaaaaaaaaallllllllllllllll
105 * -string.... -
106 */
107 enum UnaryCondition {
108 IS_NULL = 0,
109 IS_NOT_NULL = 1
110 };
111
112 enum BinaryCondition {
113 EQ = 0,
114 NE = 1,
115 LT = 2,
116 LE = 3,
117 GT = 4,
118 GE = 5,
119 LIKE = 6,
120 NOT_LIKE = 7
121 };
122 static Uint32 BranchCol(BinaryCondition cond,
123 Uint32 arrayLengthDiff, Uint32 varchar, bool nopad);
124 static Uint32 BranchCol_2(Uint32 AttrId);
125 static Uint32 BranchCol_2(Uint32 AttrId, Uint32 Len);
126
127 static Uint32 getBinaryCondition(Uint32 op1);
128 static Uint32 getArrayLengthDiff(Uint32 op1);
129 static Uint32 isVarchar(Uint32 op1);
130 static Uint32 isNopad(Uint32 op1);
131 static Uint32 getBranchCol_AttrId(Uint32 op2);
132 static Uint32 getBranchCol_Len(Uint32 op2);
133
134 /**
135 * Macros for decoding code
136 */
137 static Uint32 getOpCode(Uint32 op);
138 static Uint32 getReg1(Uint32 op);
139 static Uint32 getReg2(Uint32 op);
140 static Uint32 getReg3(Uint32 op);
141 };
142
143 inline
144 Uint32
Read(Uint32 AttrId,Uint32 Register)145 Interpreter::Read(Uint32 AttrId, Uint32 Register){
146 return (AttrId << 16) + (Register << 6) + READ_ATTR_INTO_REG;
147 }
148
149 inline
150 Uint32
Write(Uint32 AttrId,Uint32 Register)151 Interpreter::Write(Uint32 AttrId, Uint32 Register){
152 return (AttrId << 16) + (Register << 6) + WRITE_ATTR_FROM_REG;
153 }
154
155 inline
156 Uint32
LoadConst16(Uint32 Register,Uint32 Value)157 Interpreter::LoadConst16(Uint32 Register, Uint32 Value){
158 return (Value << 16) + (Register << 6) + LOAD_CONST16;
159 }
160
161 inline
162 Uint32
LoadConst32(Uint32 Register)163 Interpreter::LoadConst32(Uint32 Register){
164 return (Register << 6) + LOAD_CONST32;
165 }
166
167 inline
168 Uint32
LoadConst64(Uint32 Register)169 Interpreter::LoadConst64(Uint32 Register){
170 return (Register << 6) + LOAD_CONST64;
171 }
172
173 inline
174 Uint32
Add(Uint32 Dcoleg,Uint32 SrcReg1,Uint32 SrcReg2)175 Interpreter::Add(Uint32 Dcoleg, Uint32 SrcReg1, Uint32 SrcReg2){
176 return (SrcReg1 << 6) + (SrcReg2 << 9) + (Dcoleg << 16) + ADD_REG_REG;
177 }
178
179 inline
180 Uint32
Sub(Uint32 Dcoleg,Uint32 SrcReg1,Uint32 SrcReg2)181 Interpreter::Sub(Uint32 Dcoleg, Uint32 SrcReg1, Uint32 SrcReg2){
182 return (SrcReg1 << 6) + (SrcReg2 << 9) + (Dcoleg << 16) + SUB_REG_REG;
183 }
184
185 inline
186 Uint32
Branch(Uint32 Inst,Uint32 Reg1,Uint32 Reg2)187 Interpreter::Branch(Uint32 Inst, Uint32 Reg1, Uint32 Reg2){
188 return (Reg1 << 9) + (Reg2 << 6) + Inst;
189 }
190
191 inline
192 Uint32
BranchCol(BinaryCondition cond,Uint32 arrayLengthDiff,Uint32 varchar,bool nopad)193 Interpreter::BranchCol(BinaryCondition cond,
194 Uint32 arrayLengthDiff,
195 Uint32 varchar, bool nopad){
196 //ndbout_c("BranchCol: cond=%d diff=%u varchar=%u nopad=%d",
197 //cond, arrayLengthDiff, varchar, nopad);
198 return
199 BRANCH_ATTR_OP_ARG +
200 (arrayLengthDiff << 9) +
201 (varchar << 11) +
202 (cond << 12) +
203 (nopad << 15);
204 }
205
206 inline
207 Uint32
BranchCol_2(Uint32 AttrId,Uint32 Len)208 Interpreter::BranchCol_2(Uint32 AttrId, Uint32 Len){
209 return (AttrId << 16) + Len;
210 }
211
212 inline
213 Uint32
BranchCol_2(Uint32 AttrId)214 Interpreter::BranchCol_2(Uint32 AttrId){
215 return (AttrId << 16);
216 }
217
218 inline
219 Uint32
getBinaryCondition(Uint32 op)220 Interpreter::getBinaryCondition(Uint32 op){
221 return (op >> 12) & 0x7;
222 }
223
224 inline
225 Uint32
getArrayLengthDiff(Uint32 op)226 Interpreter::getArrayLengthDiff(Uint32 op){
227 return (op >> 9) & 0x3;
228 }
229
230 inline
231 Uint32
isVarchar(Uint32 op)232 Interpreter::isVarchar(Uint32 op){
233 return (op >> 11) & 1;
234 }
235
236 inline
237 Uint32
isNopad(Uint32 op)238 Interpreter::isNopad(Uint32 op){
239 return (op >> 15) & 1;
240 }
241
242 inline
243 Uint32
getBranchCol_AttrId(Uint32 op)244 Interpreter::getBranchCol_AttrId(Uint32 op){
245 return (op >> 16) & 0xFFFF;
246 }
247
248 inline
249 Uint32
getBranchCol_Len(Uint32 op)250 Interpreter::getBranchCol_Len(Uint32 op){
251 return op & 0xFFFF;
252 }
253
254 inline
255 Uint32
ExitOK()256 Interpreter::ExitOK(){
257 return EXIT_OK;
258 }
259
260 inline
261 Uint32
getOpCode(Uint32 op)262 Interpreter::getOpCode(Uint32 op){
263 return op & 0x3f;
264 }
265
266 inline
267 Uint32
getReg1(Uint32 op)268 Interpreter::getReg1(Uint32 op){
269 return (op >> 6) & 0x7;
270 }
271
272 inline
273 Uint32
getReg2(Uint32 op)274 Interpreter::getReg2(Uint32 op){
275 return (op >> 9) & 0x7;
276 }
277
278 inline
279 Uint32
getReg3(Uint32 op)280 Interpreter::getReg3(Uint32 op){
281 return (op >> 16) & 0x7;
282 }
283
284 #endif
285