tombagby-llvmruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/COPYING ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2008 Thomas Bagby
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
data/README ADDED
@@ -0,0 +1,76 @@
1
+ * What's LLVMRuby
2
+
3
+ LLVMRuby is a set of bindings making the LLVM compiler infrastructure
4
+ (http://llvm.org) usable from Ruby. This extention allows using LLVM
5
+ as an abstract assembler and reflects a good chunk of the LLVM class
6
+ hierarchy into Ruby. Included is an example of using this to build
7
+ a simple JIT compiler, written entirely in Ruby, which is able to
8
+ interact with the native Ruby 1.8/1.9 data types.
9
+
10
+ * How to build
11
+
12
+ You must get LLVM from svn and build it separately:
13
+
14
+ $ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
15
+
16
+ Make sure that you configure LLVM with PIC enabled:
17
+
18
+ $ ./configure --enable-pic
19
+
20
+ Add the llvm bin directory to your path, extconf needs to be able to find llvm-conf:
21
+
22
+ $ export PATH=$PATH:/$LLVMDIR/Debug/bin
23
+
24
+ Once you have built LLVM, run extconf.rb giving it location of LLVM:
25
+
26
+ $ ruby extconf.rb --with-llvm-include=/$DIR/llvm/include --with-llvm-lib=/$DIR/llvm/Debug/lib
27
+
28
+ Run make
29
+
30
+ $ make
31
+
32
+ Run the tests (you will need Rake installed)
33
+
34
+ $ rake test
35
+
36
+ Look in test.rb to see examples of use and start messing around.
37
+
38
+ * Caveats
39
+
40
+ I created this using very latest LLVM (from svn, soon to be 2.4). Other
41
+ versions may not work. I have been trying to get the 2.3 released package
42
+ to work, only one conditional typedef is required, but it complaining about
43
+ fPIC stuff :(
44
+
45
+ I primarily develop this on my home machine which is 64bit Fedora. I
46
+ occasionally test it on a 32bit CentOS machine, and recently tested it
47
+ on a 32bit MacBook. It built and passed tests with no issues. My
48
+ knowledge of building either Ruby or LLVM on Windows is minimal. It
49
+ should be doable, but I don't believe LLVM currently is usable with
50
+ VC++, which is the main compiler for Ruby on Windows, so you may run
51
+ into fun times trying to figure out a good way to make that go.
52
+
53
+ * Things that definitely do not work right now
54
+
55
+ No attempt has been made to properly free LLVM objects. This probably
56
+ isn't hard, LLVM api has easy to deal with memory management. Many LLVM
57
+ objects end up owned by modules/execution engine and shouldn't be freed
58
+ normally anyway.
59
+
60
+ There needs to be a lot more exception raising when arguments are of wrong
61
+ number/type.
62
+
63
+ Malformed LLVM functions will cause the program to abort, even just
64
+ from calling verify on a module. This seems like a bug in LLVM.
65
+ Verification in theory is slow and should be used only for debugging, but
66
+ it would nice if tests did not abort and die because of missing block
67
+ terminators or whatever.
68
+
69
+ * Copying
70
+
71
+ See the file COPYING
72
+
73
+ * Author
74
+
75
+ For questions or answers, my email is: tomatobagby@gmail.com
76
+
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ require 'rake/testtask'
2
+
3
+ desc "Run the tests"
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << 'ext'
6
+ t.test_files = FileList['test/test*.rb']
7
+ t.warning = true
8
+ end
9
+
10
+ OBJ = "ext/llvmruby." + Config::CONFIG["DLEXT"]
11
+
12
+ file "ext/Makefile" do
13
+ #cmd = "extconf.rb --with-llvm-include=`llvm-config --includedir` --with-llvm-lib=`llvm-config --libdir`"
14
+ cmd = 'extconf.rb'
15
+ Dir.chdir("ext") { ruby(cmd) }
16
+ end
17
+
18
+ file OBJ => %w(ext/Makefile) + FileList["ext/*.{cpp,c,h}"] do
19
+ Dir.chdir("ext") { sh "make" }
20
+ end
21
+
22
+ desc "Compile llvmruby extensions"
23
+ task :compile => OBJ
24
+ task :default => :compile
25
+
26
+ desc "Remove compiled files"
27
+ task :clean do |t|
28
+ for file in FileList.new("ext/*.o", "ext/Makefile", "ext/mkmf.log", OBJ)
29
+ File.delete(file) rescue true
30
+ end
31
+ end
data/ext/extconf.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'mkmf'
2
+
3
+ extension_name = 'llvmruby'
4
+
5
+ dir_config(extension_name)
6
+ dir_config('llvm', `llvm-config --includedir`.strip, `llvm-config --libdir`.strip)
7
+
8
+ have_library('stdc++')
9
+ have_library('pthread')
10
+
11
+ with_ldflags(`llvm-config --libs all`) do
12
+ create_makefile(extension_name)
13
+ end
14
+
@@ -0,0 +1,296 @@
1
+ #include "llvmruby.h"
2
+
3
+ extern VALUE cLLVMBasicBlock;
4
+ extern VALUE cLLVMBuilder;
5
+
6
+ extern "C" {
7
+ VALUE
8
+ llvm_basic_block_wrap(BasicBlock* bb) {
9
+ return Data_Wrap_Struct(cLLVMBasicBlock, NULL, NULL, bb);
10
+ }
11
+
12
+ VALUE
13
+ llvm_basic_block_size(VALUE self) {
14
+ BasicBlock *bb = LLVM_BASIC_BLOCK(self);
15
+ return INT2NUM(bb->size());
16
+ }
17
+
18
+ VALUE
19
+ llvm_basic_block_get_instruction_list(VALUE self) {
20
+ BasicBlock *bb = LLVM_BASIC_BLOCK(self);
21
+ VALUE ins_array = rb_ary_new();
22
+ BasicBlock::iterator ins = bb->begin();
23
+ while(ins != bb->end()) {
24
+ Instruction *i = ins++;
25
+ rb_ary_push(ins_array, llvm_instruction_wrap(i));
26
+ }
27
+ return ins_array;
28
+ }
29
+
30
+ VALUE
31
+ llvm_basic_block_builder(VALUE self) {
32
+ BasicBlock* bb;
33
+ Data_Get_Struct(self, BasicBlock, bb);
34
+ IRBuilder<> *builder = new IRBuilder<>(bb);
35
+ return Data_Wrap_Struct(cLLVMBuilder, NULL, NULL, builder);
36
+ }
37
+
38
+ #define DATA_GET_BUILDER IRBuilder<> *builder; Data_Get_Struct(self, IRBuilder<>, builder);
39
+ #define DATA_GET_BLOCK BasicBlock *bb; CHECK_TYPE(rbb, cLLVMBasicBlock); Data_Get_Struct(rbb, BasicBlock, bb);
40
+
41
+ VALUE
42
+ llvm_builder_set_insert_point(VALUE self, VALUE rbb) {
43
+ DATA_GET_BUILDER
44
+ DATA_GET_BLOCK
45
+ builder->SetInsertPoint(bb);
46
+ return self;
47
+ }
48
+
49
+ VALUE
50
+ llvm_builder_bin_op(VALUE self, VALUE rbin_op, VALUE rv1, VALUE rv2) {
51
+ Check_Type(rbin_op, T_FIXNUM);
52
+ //CHECK_TYPE(rv1, cLLVMValue);
53
+ //CHECK_TYPE(rv2, cLLVMValue);
54
+ DATA_GET_BUILDER
55
+
56
+ Instruction::BinaryOps bin_op = (Instruction::BinaryOps)FIX2INT(rbin_op);
57
+
58
+ Value *v1, *v2;
59
+ Data_Get_Struct(rv1, Value, v1);
60
+ Data_Get_Struct(rv2, Value, v2);
61
+ Value *res = builder->CreateBinOp(bin_op, v1, v2);
62
+ return llvm_value_wrap(res);
63
+ }
64
+
65
+ VALUE
66
+ llvm_builder_phi(VALUE self, VALUE type) {
67
+ CHECK_TYPE(type, cLLVMType);
68
+ DATA_GET_BUILDER
69
+ PHINode *v = builder->CreatePHI(LLVM_TYPE(type));
70
+ return Data_Wrap_Struct(cLLVMPhi, NULL, NULL, v);
71
+ }
72
+
73
+ VALUE
74
+ llvm_phi_add_incoming(VALUE self, VALUE val, VALUE rbb) {
75
+ CHECK_TYPE(val, cLLVMValue);
76
+ DATA_GET_BLOCK
77
+ PHINode *phi = LLVM_PHI(self);
78
+ phi->addIncoming(LLVM_VAL(val), bb);
79
+ return self;
80
+ }
81
+
82
+ VALUE
83
+ llvm_builder_return(VALUE self, VALUE rv) {
84
+ //CHECK_TYPE(rv, cLLVMValue);
85
+ DATA_GET_BUILDER
86
+ return llvm_value_wrap(builder->CreateRet(LLVM_VAL(rv)));
87
+ }
88
+
89
+ VALUE
90
+ llvm_builder_br(VALUE self, VALUE rblock) {
91
+ DATA_GET_BUILDER
92
+
93
+ BasicBlock *bb;
94
+ Data_Get_Struct(rblock, BasicBlock, bb);
95
+ return llvm_value_wrap(builder->CreateBr(bb));
96
+ }
97
+
98
+ VALUE
99
+ llvm_builder_cond_br(VALUE self, VALUE rcond, VALUE rtrue_block, VALUE rfalse_block) {
100
+ DATA_GET_BUILDER
101
+
102
+ Value *cond;
103
+ Data_Get_Struct(rcond, Value, cond);
104
+
105
+ BasicBlock *true_block, *false_block;
106
+ Data_Get_Struct(rtrue_block, BasicBlock, true_block);
107
+ Data_Get_Struct(rfalse_block, BasicBlock, false_block);
108
+
109
+ return llvm_value_wrap(builder->CreateCondBr(cond, true_block, false_block));
110
+ }
111
+
112
+ VALUE
113
+ llvm_builder_switch(VALUE self, VALUE rv, VALUE rdefault) {
114
+ DATA_GET_BUILDER
115
+
116
+ BasicBlock *deflt;
117
+ Data_Get_Struct(rdefault, BasicBlock, deflt);
118
+
119
+ Value *v;
120
+ Data_Get_Struct(rv, Value, v);
121
+
122
+ Value* switch_instr = builder->CreateSwitch(v, deflt);
123
+ return Data_Wrap_Struct(cLLVMSwitchInst, NULL, NULL, switch_instr);
124
+ }
125
+
126
+ VALUE
127
+ llvm_builder_malloc(VALUE self, VALUE rtype, VALUE rsize) {
128
+ DATA_GET_BUILDER
129
+
130
+ const Type *type;
131
+ Data_Get_Struct(rtype, Type, type);
132
+
133
+ Value *size = ConstantInt::get(Type::Int32Ty, FIX2INT(rsize));
134
+ Value *v = builder->CreateMalloc(type, size);
135
+ return llvm_value_wrap(v);
136
+ }
137
+
138
+ VALUE
139
+ llvm_builder_free(VALUE self, VALUE rptr) {
140
+ DATA_GET_BUILDER
141
+ Value *v = LLVM_VAL(rptr);
142
+ builder->CreateFree(v);
143
+ return Qtrue;
144
+ }
145
+
146
+ VALUE
147
+ llvm_builder_alloca(VALUE self, VALUE rtype, VALUE rsize) {
148
+ DATA_GET_BUILDER
149
+
150
+ const Type* type;
151
+ Data_Get_Struct(rtype, Type, type);
152
+
153
+ Value *size = ConstantInt::get(Type::Int32Ty, FIX2INT(rsize));
154
+ Value *v = builder->CreateAlloca(type, size);
155
+ return llvm_value_wrap(v);
156
+ }
157
+
158
+ VALUE
159
+ llvm_builder_load(VALUE self, VALUE rptr) {
160
+ DATA_GET_BUILDER
161
+
162
+ Value *ptr;
163
+ Data_Get_Struct(rptr, Value, ptr);
164
+ return llvm_value_wrap(builder->CreateLoad(ptr));
165
+ }
166
+
167
+ VALUE
168
+ llvm_builder_store(VALUE self, VALUE rv, VALUE rptr) {
169
+ DATA_GET_BUILDER
170
+
171
+ Value *v, *ptr;
172
+ Data_Get_Struct(rv, Value, v);
173
+ Data_Get_Struct(rptr, Value, ptr);
174
+ return llvm_value_wrap(builder->CreateStore(v, ptr));
175
+ }
176
+
177
+ VALUE
178
+ llvm_builder_icmp(VALUE self, VALUE pred, VALUE lhs, VALUE rhs) {
179
+ DATA_GET_BUILDER
180
+
181
+ CmpInst::Predicate p = (CmpInst::Predicate)FIX2INT(pred);
182
+ Value *v = builder->CreateICmp(p, LLVM_VAL(lhs), LLVM_VAL(rhs));
183
+ return llvm_value_wrap(v);
184
+ }
185
+
186
+ VALUE
187
+ llvm_builder_fcmp(VALUE self, VALUE pred, VALUE lhs, VALUE rhs) {
188
+ DATA_GET_BUILDER
189
+
190
+ CmpInst::Predicate p = (CmpInst::Predicate)FIX2INT(pred);
191
+ Value *v = builder->CreateFCmp(p, LLVM_VAL(lhs), LLVM_VAL(rhs));
192
+ return llvm_value_wrap(v);
193
+ }
194
+
195
+ VALUE
196
+ llvm_builder_gep(VALUE self, VALUE rptr, VALUE ridx) {
197
+ DATA_GET_BUILDER
198
+
199
+ Value *ptr, *idx;
200
+ Data_Get_Struct(rptr, Value, ptr);
201
+ Data_Get_Struct(ridx, Value, idx);
202
+ return llvm_value_wrap(builder->CreateGEP(ptr, idx));
203
+ }
204
+
205
+ VALUE
206
+ llvm_builder_struct_gep(VALUE self, VALUE rptr, VALUE ridx) {
207
+ DATA_GET_BUILDER
208
+
209
+ Value *ptr;
210
+ Data_Get_Struct(rptr, Value, ptr);
211
+ return llvm_value_wrap(builder->CreateStructGEP(ptr, FIX2INT(ridx)));
212
+ }
213
+
214
+ VALUE
215
+ llvm_builder_cast(VALUE self, VALUE rop, VALUE rv, VALUE rdest_ty) {
216
+ DATA_GET_BUILDER
217
+
218
+ Instruction::CastOps op = (Instruction::CastOps)FIX2INT(rop);
219
+
220
+ Value *v;
221
+ Data_Get_Struct(rv, Value, v);
222
+
223
+ Type *dest_ty;
224
+ Data_Get_Struct(rdest_ty, Type, dest_ty);
225
+
226
+ return llvm_value_wrap(builder->CreateCast(op, v, dest_ty));
227
+ }
228
+
229
+ VALUE
230
+ llvm_builder_int_to_ptr(VALUE self, VALUE ri, VALUE rtype) {
231
+ DATA_GET_BUILDER
232
+
233
+ Value *i;
234
+ Data_Get_Struct(ri, Value, i);
235
+
236
+ const Type* type;
237
+ Data_Get_Struct(rtype, Type, type);
238
+
239
+ return llvm_value_wrap(builder->CreateIntToPtr(i, type));
240
+ }
241
+
242
+ VALUE llvm_builder_int_cast(VALUE self, VALUE i, VALUE type, VALUE sign) {
243
+ DATA_GET_BUILDER
244
+ bool isSigned = (sign != Qnil && sign != Qfalse);
245
+ return llvm_value_wrap(builder->CreateIntCast(LLVM_VAL(i), LLVM_TYPE(type), isSigned));
246
+ }
247
+
248
+ VALUE
249
+ llvm_builder_call(int argc, VALUE* argv, VALUE self) {
250
+ DATA_GET_BUILDER
251
+
252
+ Function *callee = LLVM_FUNCTION(argv[0]);
253
+ int num_args = argc-1;
254
+ Value** args = (Value**)alloca(num_args*sizeof(Value*));
255
+ for(int i = 0; i < num_args; ++i) {
256
+ args[i] = LLVM_VAL(argv[i+1]);
257
+ }
258
+ return llvm_value_wrap(builder->CreateCall(callee, args, args+num_args));
259
+ }
260
+
261
+ VALUE
262
+ llvm_builder_insert_element(VALUE self, VALUE rv, VALUE rnv, VALUE ridx) {
263
+ DATA_GET_BUILDER
264
+
265
+ Value *v, *nv, *idx;
266
+ Data_Get_Struct(rv, Value, v);
267
+ Data_Get_Struct(rnv, Value, nv);
268
+ Data_Get_Struct(ridx, Value, idx);
269
+
270
+ return llvm_value_wrap(builder->CreateInsertElement(v, nv, idx));
271
+ }
272
+
273
+ VALUE
274
+ llvm_builder_extract_element(VALUE self, VALUE rv, VALUE ridx) {
275
+ DATA_GET_BUILDER
276
+
277
+ Value *v, *idx;
278
+ Data_Get_Struct(rv, Value, v);
279
+ Data_Get_Struct(ridx, Value, idx);
280
+
281
+ return llvm_value_wrap(builder->CreateExtractElement(v, idx));
282
+ }
283
+
284
+ VALUE
285
+ llvm_builder_get_global(VALUE self) {
286
+ GlobalVariable *g = new GlobalVariable(Type::Int64Ty, false, GlobalValue::ExternalLinkage, 0, "shakalaka");
287
+ return llvm_value_wrap(g);
288
+ }
289
+
290
+ VALUE
291
+ llvm_builder_create_global_string_ptr(VALUE self, VALUE str) {
292
+ DATA_GET_BUILDER
293
+ Value *v = builder->CreateGlobalStringPtr(StringValuePtr(str));
294
+ return llvm_value_wrap(v);
295
+ }
296
+ }
@@ -0,0 +1,48 @@
1
+ #include "llvmruby.h"
2
+ #include <sstream>
3
+
4
+ extern "C" {
5
+ VALUE
6
+ llvm_function_wrap(Function *f) {
7
+ return Data_Wrap_Struct(cLLVMFunction, NULL, NULL, f);
8
+ }
9
+
10
+ VALUE
11
+ llvm_function_create_block(VALUE self) {
12
+ BasicBlock *bb = BasicBlock::Create("bb", LLVM_FUNCTION(self));
13
+ return llvm_basic_block_wrap(bb);
14
+ }
15
+
16
+ VALUE
17
+ llvm_function_arguments(VALUE self) {
18
+ Function *f = LLVM_FUNCTION(self);
19
+ VALUE arg_array = rb_ary_new();
20
+ Function::arg_iterator args = f->arg_begin();
21
+ while(args != f->arg_end()) {
22
+ Value *arg = args++;
23
+ rb_ary_push(arg_array, llvm_value_wrap(arg));
24
+ }
25
+ return arg_array;
26
+ }
27
+
28
+ VALUE
29
+ llvm_function_inspect(VALUE self) {
30
+ Function *f = LLVM_FUNCTION(self);
31
+ std::ostringstream strstrm;
32
+ strstrm << *f;
33
+ return rb_str_new2(strstrm.str().c_str());
34
+ }
35
+
36
+ VALUE
37
+ llvm_function_get_basic_block_list(VALUE self) {
38
+ Function *f = LLVM_FUNCTION(self);
39
+ VALUE bb_array = rb_ary_new();
40
+ Function::iterator bbs = f->begin();
41
+ while(bbs != f->end()) {
42
+ BasicBlock *bb = bbs++;
43
+ rb_ary_push(bb_array, llvm_basic_block_wrap(bb));
44
+ }
45
+ return bb_array;
46
+ }
47
+
48
+ }
@@ -0,0 +1,125 @@
1
+ #include "llvmruby.h"
2
+ #include <sstream>
3
+
4
+ extern VALUE cLLVMInstruction;
5
+ extern VALUE cLLVMBinaryOps;
6
+
7
+ extern "C" {
8
+
9
+ VALUE
10
+ llvm_instruction_wrap(Instruction* i) {
11
+ return Data_Wrap_Struct(cLLVMInstruction, NULL, NULL, i);
12
+ }
13
+
14
+ VALUE
15
+ llvm_instruction_inspect(VALUE self) {
16
+ Instruction *i = LLVM_INSTRUCTION(self);
17
+ std::ostringstream strstrm;
18
+ strstrm << *i;
19
+ return rb_str_new2(strstrm.str().c_str());
20
+ }
21
+
22
+ VALUE
23
+ llvm_instruction_get_opcode_name(VALUE self) {
24
+ Instruction *i = LLVM_INSTRUCTION(self);
25
+ std::string name = i->getOpcodeName();
26
+ return rb_str_new2(name.c_str());
27
+ }
28
+
29
+ #define DATA_GET_SWITCH_INST SwitchInst *si; Data_Get_Struct(self, SwitchInst, si);
30
+
31
+ VALUE
32
+ llvm_switch_inst_get_default_dest(VALUE self) {
33
+ DATA_GET_SWITCH_INST
34
+ BasicBlock *bb = si->getDefaultDest();
35
+ return llvm_basic_block_wrap(bb);
36
+ }
37
+
38
+ VALUE
39
+ llvm_switch_inst_get_num_cases(VALUE self) {
40
+ DATA_GET_SWITCH_INST
41
+ return INT2FIX(si->getNumCases());
42
+ }
43
+
44
+ VALUE
45
+ llvm_switch_inst_add_case(VALUE self, VALUE rci, VALUE rbb) {
46
+ DATA_GET_SWITCH_INST
47
+
48
+ ConstantInt *ci;
49
+ Data_Get_Struct(rci, ConstantInt, ci);
50
+
51
+ BasicBlock *bb;
52
+ Data_Get_Struct(rbb, BasicBlock, bb);
53
+
54
+ si->addCase(ci, bb);
55
+ return self;
56
+ }
57
+
58
+
59
+ #define DEFINE_INST(type, name) rb_define_const(cLLVMInstruction, #name, INT2FIX(Instruction::name));
60
+ #define DEFINE_BINARY_INST(name) DEFINE_INST(cLLVMBinaryOps, name)
61
+ #define DEFINE_PRED(name) rb_define_const(cLLVMInstruction, #name, INT2FIX(ICmpInst::name));
62
+ #define DEFINE_FPRED(name) rb_define_const(cLLVMInstruction, #name, INT2FIX(FCmpInst::name));
63
+ #define DEFINE_CAST(name) rb_define_const(cLLVMInstruction, #name, INT2FIX(Instruction::name));
64
+
65
+ void init_instructions() {
66
+ // Standard binary operators
67
+ DEFINE_BINARY_INST(Add)
68
+ DEFINE_BINARY_INST(Sub)
69
+ DEFINE_BINARY_INST(Mul)
70
+ DEFINE_BINARY_INST(UDiv)
71
+ DEFINE_BINARY_INST(SDiv)
72
+ DEFINE_BINARY_INST(FDiv)
73
+ DEFINE_BINARY_INST(URem)
74
+ DEFINE_BINARY_INST(SRem)
75
+ DEFINE_BINARY_INST(FRem)
76
+
77
+ // Logical operators (integer operands)
78
+ DEFINE_BINARY_INST(Shl) // Shift left (logical)
79
+ DEFINE_BINARY_INST(LShr) // Shift right (logical)
80
+ DEFINE_BINARY_INST(AShr) // shift right (arithmetic)
81
+ DEFINE_BINARY_INST(And)
82
+ DEFINE_BINARY_INST(Or)
83
+ DEFINE_BINARY_INST(Xor)
84
+
85
+ // Integer predicates
86
+ DEFINE_PRED(ICMP_EQ) // equal
87
+ DEFINE_PRED(ICMP_NE) // not equal
88
+ DEFINE_PRED(ICMP_UGT) // unsigned greater than
89
+ DEFINE_PRED(ICMP_UGE) // unsigned greater or equal
90
+ DEFINE_PRED(ICMP_ULT) // unsigned less than
91
+ DEFINE_PRED(ICMP_ULE) // unsigned less or equal
92
+ DEFINE_PRED(ICMP_SGT) // signed greater than
93
+ DEFINE_PRED(ICMP_SGE) // signed greater or equal
94
+ DEFINE_PRED(ICMP_SLT) // signed less than
95
+ DEFINE_PRED(ICMP_SLE) // signed less or equal
96
+
97
+ DEFINE_FPRED(FCMP_OEQ)
98
+ DEFINE_FPRED(FCMP_OGT)
99
+ DEFINE_FPRED(FCMP_OGE)
100
+ DEFINE_FPRED(FCMP_OLT)
101
+ DEFINE_FPRED(FCMP_OLE)
102
+ DEFINE_FPRED(FCMP_ONE)
103
+ DEFINE_FPRED(FCMP_ORD)
104
+ DEFINE_FPRED(FCMP_UNO)
105
+ DEFINE_FPRED(FCMP_UEQ)
106
+ DEFINE_FPRED(FCMP_UGT)
107
+ DEFINE_FPRED(FCMP_UGE)
108
+ DEFINE_FPRED(FCMP_ULT)
109
+ DEFINE_FPRED(FCMP_ULE)
110
+ DEFINE_FPRED(FCMP_UNE)
111
+
112
+ DEFINE_CAST(Trunc)
113
+ DEFINE_CAST(ZExt)
114
+ DEFINE_CAST(SExt)
115
+ DEFINE_CAST(FPToUI)
116
+ DEFINE_CAST(FPToSI)
117
+ DEFINE_CAST(UIToFP)
118
+ DEFINE_CAST(SIToFP)
119
+ DEFINE_CAST(FPTrunc)
120
+ DEFINE_CAST(FPExt)
121
+ DEFINE_CAST(PtrToInt)
122
+ DEFINE_CAST(IntToPtr)
123
+ DEFINE_CAST(BitCast)
124
+ }
125
+ }