vectornode.hpp 19.4 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23
 */

24 25 26 27 28 29 30 31
#ifndef SHARE_VM_OPTO_VECTORNODE_HPP
#define SHARE_VM_OPTO_VECTORNODE_HPP

#include "opto/matcher.hpp"
#include "opto/memnode.hpp"
#include "opto/node.hpp"
#include "opto/opcodes.hpp"

D
duke 已提交
32 33
//------------------------------VectorNode--------------------------------------
// Vector Operation
34
class VectorNode : public TypeNode {
D
duke 已提交
35 36
 public:

37
  VectorNode(Node* n1, const TypeVect* vt) : TypeNode(vt, 2) {
K
kvn 已提交
38
    init_class_id(Class_Vector);
39
    init_req(1, n1);
D
duke 已提交
40
  }
41
  VectorNode(Node* n1, Node* n2, const TypeVect* vt) : TypeNode(vt, 3) {
K
kvn 已提交
42
    init_class_id(Class_Vector);
43 44
    init_req(1, n1);
    init_req(2, n2);
D
duke 已提交
45 46
  }

47 48
  const TypeVect* vect_type() const { return type()->is_vect(); }
  uint length() const { return vect_type()->length(); } // Vector length
D
duke 已提交
49

50
  virtual int Opcode() const;
D
duke 已提交
51

52
  virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(vect_type()->length_in_bytes()); }
D
duke 已提交
53 54 55

  static VectorNode* scalar2vector(Compile* C, Node* s, uint vlen, const Type* opd_t);

56 57 58 59
  static VectorNode* make(Compile* C, int opc, Node* n1, Node* n2, uint vlen, BasicType bt);

  static int  opcode(int opc, uint vlen, BasicType bt);
  static bool implemented(int opc, uint vlen, BasicType bt);
D
duke 已提交
60 61 62 63 64 65 66 67 68

};

//===========================Vector=ALU=Operations====================================

//------------------------------AddVBNode---------------------------------------
// Vector add byte
class AddVBNode : public VectorNode {
 public:
69
  AddVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
70 71 72 73
  virtual int Opcode() const;
};

//------------------------------AddVSNode---------------------------------------
74
// Vector add char/short
D
duke 已提交
75 76
class AddVSNode : public VectorNode {
 public:
77
  AddVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
78 79 80 81 82 83 84
  virtual int Opcode() const;
};

//------------------------------AddVINode---------------------------------------
// Vector add int
class AddVINode : public VectorNode {
 public:
85
  AddVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
86 87 88 89 90 91 92
  virtual int Opcode() const;
};

//------------------------------AddVLNode---------------------------------------
// Vector add long
class AddVLNode : public VectorNode {
 public:
93
  AddVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
94 95 96 97 98 99 100
  virtual int Opcode() const;
};

//------------------------------AddVFNode---------------------------------------
// Vector add float
class AddVFNode : public VectorNode {
 public:
101
  AddVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
102 103 104 105 106 107 108
  virtual int Opcode() const;
};

//------------------------------AddVDNode---------------------------------------
// Vector add double
class AddVDNode : public VectorNode {
 public:
109
  AddVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
110 111 112 113 114 115 116
  virtual int Opcode() const;
};

//------------------------------SubVBNode---------------------------------------
// Vector subtract byte
class SubVBNode : public VectorNode {
 public:
117
  SubVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
118 119 120 121 122 123 124
  virtual int Opcode() const;
};

//------------------------------SubVSNode---------------------------------------
// Vector subtract short
class SubVSNode : public VectorNode {
 public:
125
  SubVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
126 127 128 129 130 131 132
  virtual int Opcode() const;
};

//------------------------------SubVINode---------------------------------------
// Vector subtract int
class SubVINode : public VectorNode {
 public:
133
  SubVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
134 135 136 137 138 139 140
  virtual int Opcode() const;
};

//------------------------------SubVLNode---------------------------------------
// Vector subtract long
class SubVLNode : public VectorNode {
 public:
141
  SubVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
142 143 144 145 146 147 148
  virtual int Opcode() const;
};

//------------------------------SubVFNode---------------------------------------
// Vector subtract float
class SubVFNode : public VectorNode {
 public:
149
  SubVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
150 151 152 153 154 155 156
  virtual int Opcode() const;
};

//------------------------------SubVDNode---------------------------------------
// Vector subtract double
class SubVDNode : public VectorNode {
 public:
157
  SubVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
158 159 160 161 162 163 164
  virtual int Opcode() const;
};

//------------------------------MulVFNode---------------------------------------
// Vector multiply float
class MulVFNode : public VectorNode {
 public:
165
  MulVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
166 167 168 169 170 171 172
  virtual int Opcode() const;
};

//------------------------------MulVDNode---------------------------------------
// Vector multiply double
class MulVDNode : public VectorNode {
 public:
173
  MulVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
174 175 176 177 178 179 180
  virtual int Opcode() const;
};

//------------------------------DivVFNode---------------------------------------
// Vector divide float
class DivVFNode : public VectorNode {
 public:
181
  DivVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
182 183 184 185 186 187 188
  virtual int Opcode() const;
};

//------------------------------DivVDNode---------------------------------------
// Vector Divide double
class DivVDNode : public VectorNode {
 public:
189
  DivVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
190 191 192 193 194 195 196
  virtual int Opcode() const;
};

//------------------------------LShiftVBNode---------------------------------------
// Vector lshift byte
class LShiftVBNode : public VectorNode {
 public:
197
  LShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
198 199 200 201 202 203 204
  virtual int Opcode() const;
};

//------------------------------LShiftVSNode---------------------------------------
// Vector lshift shorts
class LShiftVSNode : public VectorNode {
 public:
205
  LShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
206 207 208 209 210 211 212
  virtual int Opcode() const;
};

//------------------------------LShiftVINode---------------------------------------
// Vector lshift ints
class LShiftVINode : public VectorNode {
 public:
213
  LShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
214 215 216 217 218
  virtual int Opcode() const;
};

//------------------------------URShiftVBNode---------------------------------------
// Vector urshift bytes
219
class RShiftVBNode : public VectorNode {
D
duke 已提交
220
 public:
221
  RShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
222 223 224 225 226
  virtual int Opcode() const;
};

//------------------------------URShiftVSNode---------------------------------------
// Vector urshift shorts
227
class RShiftVSNode : public VectorNode {
D
duke 已提交
228
 public:
229
  RShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
230 231 232 233 234
  virtual int Opcode() const;
};

//------------------------------URShiftVINode---------------------------------------
// Vector urshift ints
235
class RShiftVINode : public VectorNode {
D
duke 已提交
236
 public:
237
  RShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
238 239 240 241 242 243 244
  virtual int Opcode() const;
};

//------------------------------AndVNode---------------------------------------
// Vector and
class AndVNode : public VectorNode {
 public:
245
  AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
246 247 248 249 250 251 252
  virtual int Opcode() const;
};

//------------------------------OrVNode---------------------------------------
// Vector or
class OrVNode : public VectorNode {
 public:
253
  OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
254 255 256 257 258 259 260
  virtual int Opcode() const;
};

//------------------------------XorVNode---------------------------------------
// Vector xor
class XorVNode : public VectorNode {
 public:
261
  XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
D
duke 已提交
262 263 264
  virtual int Opcode() const;
};

265
//================================= M E M O R Y ===============================
D
duke 已提交
266

267 268 269
//------------------------------LoadVectorNode---------------------------------
// Load Vector from memory
class LoadVectorNode : public LoadNode {
D
duke 已提交
270
 public:
271 272 273
  LoadVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt)
    : LoadNode(c, mem, adr, at, vt) {
    init_class_id(Class_LoadVector);
D
duke 已提交
274 275
  }

276 277
  const TypeVect* vect_type() const { return type()->is_vect(); }
  uint length() const { return vect_type()->length(); } // Vector length
D
duke 已提交
278 279 280

  virtual int Opcode() const;

281 282 283
  virtual uint ideal_reg() const  { return Matcher::vector_ideal_reg(memory_size()); }
  virtual BasicType memory_type() const { return T_VOID; }
  virtual int memory_size() const { return vect_type()->length_in_bytes(); }
D
duke 已提交
284

285
  virtual int store_Opcode() const { return Op_StoreVector; }
D
duke 已提交
286

287 288
  static LoadVectorNode* make(Compile* C, int opc, Node* ctl, Node* mem,
                              Node* adr, const TypePtr* atyp, uint vlen, BasicType bt);
D
duke 已提交
289 290
};

291 292 293
//------------------------------StoreVectorNode--------------------------------
// Store Vector to memory
class StoreVectorNode : public StoreNode {
D
duke 已提交
294
 public:
295 296 297 298
  StoreVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
    : StoreNode(c, mem, adr, at, val) {
    assert(val->is_Vector() || val->is_LoadVector(), "sanity");
    init_class_id(Class_StoreVector);
D
duke 已提交
299 300
  }

301 302
  const TypeVect* vect_type() const { return in(MemNode::ValueIn)->bottom_type()->is_vect(); }
  uint length() const { return vect_type()->length(); } // Vector length
D
duke 已提交
303

304
  virtual int Opcode() const;
D
duke 已提交
305

306
  virtual uint ideal_reg() const  { return Matcher::vector_ideal_reg(memory_size()); }
D
duke 已提交
307
  virtual BasicType memory_type() const { return T_VOID; }
308
  virtual int memory_size() const { return vect_type()->length_in_bytes(); }
D
duke 已提交
309

310
  static StoreVectorNode* make(Compile* C, int opc, Node* ctl, Node* mem,
K
kvn 已提交
311
                               Node* adr, const TypePtr* atyp, Node* val,
D
duke 已提交
312 313 314 315
                               uint vlen);
};


316
//=========================Promote_Scalar_to_Vector============================
D
duke 已提交
317

318 319 320
//------------------------------ReplicateBNode---------------------------------
// Replicate byte scalar to be vector
class ReplicateBNode : public VectorNode {
D
duke 已提交
321
 public:
322
  ReplicateBNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
D
duke 已提交
323 324 325
  virtual int Opcode() const;
};

326 327 328
//------------------------------ReplicateSNode---------------------------------
// Replicate short scalar to be vector
class ReplicateSNode : public VectorNode {
D
duke 已提交
329
 public:
330
  ReplicateSNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
D
duke 已提交
331 332 333
  virtual int Opcode() const;
};

334 335 336
//------------------------------ReplicateINode---------------------------------
// Replicate int scalar to be vector
class ReplicateINode : public VectorNode {
D
duke 已提交
337
 public:
338
  ReplicateINode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
D
duke 已提交
339 340 341
  virtual int Opcode() const;
};

342 343 344
//------------------------------ReplicateLNode---------------------------------
// Replicate long scalar to be vector
class ReplicateLNode : public VectorNode {
D
duke 已提交
345
 public:
346
  ReplicateLNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
D
duke 已提交
347 348 349
  virtual int Opcode() const;
};

350 351 352
//------------------------------ReplicateFNode---------------------------------
// Replicate float scalar to be vector
class ReplicateFNode : public VectorNode {
D
duke 已提交
353
 public:
354
  ReplicateFNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
D
duke 已提交
355 356 357
  virtual int Opcode() const;
};

358 359 360
//------------------------------ReplicateDNode---------------------------------
// Replicate double scalar to be vector
class ReplicateDNode : public VectorNode {
D
duke 已提交
361
 public:
362
  ReplicateDNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
D
duke 已提交
363 364 365
  virtual int Opcode() const;
};

366
//========================Pack_Scalars_into_a_Vector===========================
D
duke 已提交
367 368 369 370 371

//------------------------------PackNode---------------------------------------
// Pack parent class (not for code generation).
class PackNode : public VectorNode {
 public:
372 373
  PackNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
  PackNode(Node* in1, Node* n2, const TypeVect* vt) : VectorNode(in1, n2, vt) {}
D
duke 已提交
374 375
  virtual int Opcode() const;

376 377
  void add_opd(uint i, Node* n) {
    init_req(i+1, n);
D
duke 已提交
378 379 380 381 382
  }

  // Create a binary tree form for Packs. [lo, hi) (half-open) range
  Node* binaryTreePack(Compile* C, int lo, int hi);

383
  static PackNode* make(Compile* C, Node* s, uint vlen, BasicType bt);
D
duke 已提交
384 385 386 387 388 389
};

//------------------------------PackBNode---------------------------------------
// Pack byte scalars into vector
class PackBNode : public PackNode {
 public:
390
  PackBNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
D
duke 已提交
391 392 393 394 395 396 397
  virtual int Opcode() const;
};

//------------------------------PackSNode---------------------------------------
// Pack short scalars into a vector
class PackSNode : public PackNode {
 public:
398 399
  PackSNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
  PackSNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
D
duke 已提交
400 401 402 403 404 405 406
  virtual int Opcode() const;
};

//------------------------------PackINode---------------------------------------
// Pack integer scalars into a vector
class PackINode : public PackNode {
 public:
407 408
  PackINode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
  PackINode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
D
duke 已提交
409 410 411 412 413 414 415
  virtual int Opcode() const;
};

//------------------------------PackLNode---------------------------------------
// Pack long scalars into a vector
class PackLNode : public PackNode {
 public:
416 417 418 419 420 421 422 423 424 425
  PackLNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
  PackLNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
  virtual int Opcode() const;
};

//------------------------------Pack2LNode--------------------------------------
// Pack 2 long scalars into a vector
class Pack2LNode : public PackNode {
 public:
  Pack2LNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
D
duke 已提交
426 427 428 429 430 431 432
  virtual int Opcode() const;
};

//------------------------------PackFNode---------------------------------------
// Pack float scalars into vector
class PackFNode : public PackNode {
 public:
433 434
  PackFNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
  PackFNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
D
duke 已提交
435 436 437 438 439 440 441
  virtual int Opcode() const;
};

//------------------------------PackDNode---------------------------------------
// Pack double scalars into a vector
class PackDNode : public PackNode {
 public:
442 443
  PackDNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
  PackDNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
D
duke 已提交
444 445 446
  virtual int Opcode() const;
};

447 448 449
//------------------------------Pack2DNode--------------------------------------
// Pack 2 double scalars into a vector
class Pack2DNode : public PackNode {
D
duke 已提交
450
 public:
451
  Pack2DNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
D
duke 已提交
452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467
  virtual int Opcode() const;
};


//========================Extract_Scalar_from_Vector===============================

//------------------------------ExtractNode---------------------------------------
// Extract a scalar from a vector at position "pos"
class ExtractNode : public Node {
 public:
  ExtractNode(Node* src, ConINode* pos) : Node(NULL, src, (Node*)pos) {
    assert(in(2)->get_int() >= 0, "positive constants");
  }
  virtual int Opcode() const;
  uint  pos() const { return in(2)->get_int(); }

468
  static Node* make(Compile* C, Node* v, uint position, BasicType bt);
D
duke 已提交
469 470 471 472 473 474 475 476 477 478 479 480
};

//------------------------------ExtractBNode---------------------------------------
// Extract a byte from a vector at position "pos"
class ExtractBNode : public ExtractNode {
 public:
  ExtractBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
  virtual int Opcode() const;
  virtual const Type *bottom_type() const { return TypeInt::INT; }
  virtual uint ideal_reg() const { return Op_RegI; }
};

481 482 483 484 485 486 487 488 489 490
//------------------------------ExtractUBNode--------------------------------------
// Extract a boolean from a vector at position "pos"
class ExtractUBNode : public ExtractNode {
 public:
  ExtractUBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
  virtual int Opcode() const;
  virtual const Type *bottom_type() const { return TypeInt::INT; }
  virtual uint ideal_reg() const { return Op_RegI; }
};

D
duke 已提交
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
//------------------------------ExtractCNode---------------------------------------
// Extract a char from a vector at position "pos"
class ExtractCNode : public ExtractNode {
 public:
  ExtractCNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
  virtual int Opcode() const;
  virtual const Type *bottom_type() const { return TypeInt::INT; }
  virtual uint ideal_reg() const { return Op_RegI; }
};

//------------------------------ExtractSNode---------------------------------------
// Extract a short from a vector at position "pos"
class ExtractSNode : public ExtractNode {
 public:
  ExtractSNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
  virtual int Opcode() const;
  virtual const Type *bottom_type() const { return TypeInt::INT; }
  virtual uint ideal_reg() const { return Op_RegI; }
};

//------------------------------ExtractINode---------------------------------------
// Extract an int from a vector at position "pos"
class ExtractINode : public ExtractNode {
 public:
  ExtractINode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
  virtual int Opcode() const;
  virtual const Type *bottom_type() const { return TypeInt::INT; }
  virtual uint ideal_reg() const { return Op_RegI; }
};

//------------------------------ExtractLNode---------------------------------------
// Extract a long from a vector at position "pos"
class ExtractLNode : public ExtractNode {
 public:
  ExtractLNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
  virtual int Opcode() const;
  virtual const Type *bottom_type() const { return TypeLong::LONG; }
  virtual uint ideal_reg() const { return Op_RegL; }
};

//------------------------------ExtractFNode---------------------------------------
// Extract a float from a vector at position "pos"
class ExtractFNode : public ExtractNode {
 public:
  ExtractFNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
  virtual int Opcode() const;
  virtual const Type *bottom_type() const { return Type::FLOAT; }
  virtual uint ideal_reg() const { return Op_RegF; }
};

//------------------------------ExtractDNode---------------------------------------
// Extract a double from a vector at position "pos"
class ExtractDNode : public ExtractNode {
 public:
  ExtractDNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
  virtual int Opcode() const;
  virtual const Type *bottom_type() const { return Type::DOUBLE; }
  virtual uint ideal_reg() const { return Op_RegD; }
};
550 551

#endif // SHARE_VM_OPTO_VECTORNODE_HPP