llvm.org GIT mirror llvm / b02fbfc
Eliminate tabs and trailing spaces git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21479 91177308-0d34-0410-b5e6-96231b3b80d8 Jeff Cohen 15 years ago
25 changed file(s) with 1228 addition(s) and 1229 deletion(s). Raw diff Collapse all Expand all
3838 StackerCompiler* StackerCompiler::TheInstance = 0;
3939
4040 static Statistic<> NumDefinitions(
41 "numdefs","The # of definitions encoutered while compiling Stacker");
41 "numdefs","The # of definitions encoutered while compiling Stacker");
4242
4343 StackerCompiler::StackerCompiler()
4444 : CurFilename("")
105105 ///
106106 if (filename != "-")
107107 {
108 F = fopen(filename.c_str(), "r");
109
110 if (F == 0)
111 {
112 throw ParseException(filename,
113 "Could not open file '" + filename + "'");
114 }
108 F = fopen(filename.c_str(), "r");
109
110 if (F == 0)
111 {
112 throw ParseException(filename,
113 "Could not open file '" + filename + "'");
114 }
115115 }
116116
117117 Module *Result;
118118 try
119119 {
120 // Create the module we'll return
121 TheModule = new Module( CurFilename );
120 // Create the module we'll return
121 TheModule = new Module( CurFilename );
122122
123123 // Tell the module about our runtime library
124124 TheModule->addLibrary("stkr_runtime");
125125
126 // Create a type to represent the stack. This is the same as the LLVM
127 // Assembly type [ 256 x long ]
128 stack_type = ArrayType::get( Type::LongTy, stack_size );
129
130 // Create a global variable for the stack. Note the use of appending
131 // linkage linkage so that multiple modules will make the stack larger.
132 // Also note that the last argument causes the global to be inserted
133 // automatically into the module.
134 TheStack = new GlobalVariable(
135 /*type=*/ stack_type,
136 /*isConstant=*/ false,
137 /*Linkage=*/ GlobalValue::LinkOnceLinkage,
138 /*initializer=*/ Constant::getNullValue(stack_type),
139 /*name=*/ "_stack_",
140 /*parent=*/ TheModule
141 );
142
143 // Create a global variable for indexing into the stack. Note the use
144 // of LinkOnce linkage. Only one copy of _index_ will be retained
145 // after linking
146 TheIndex = new GlobalVariable(
147 /*type=*/Type::LongTy,
148 /*isConstant=*/false,
149 /*Linkage=*/GlobalValue::LinkOnceLinkage,
150 /*initializer=*/ Constant::getNullValue(Type::LongTy),
151 /*name=*/"_index_",
152 /*parent=*/TheModule
153 );
154
155 // Create a function prototype for definitions. No parameters, no
156 // result. This is used below any time a function is created.
157 std::vector params; // No parameters
158 DefinitionType = FunctionType::get( Type::VoidTy, params, false );
159
160 // Create a function for printf(3)
161 params.push_back( PointerType::get( Type::SByteTy ) );
162 FunctionType* printf_type =
163 FunctionType::get( Type::IntTy, params, true );
164 ThePrintf = new Function(
165 printf_type, GlobalValue::ExternalLinkage, "printf", TheModule);
166
167 // Create a function for scanf(3)
168 TheScanf = new Function(
169 printf_type, GlobalValue::ExternalLinkage, "scanf", TheModule);
170
171 // Create a function for exit(3)
172 params.clear();
173 params.push_back( Type::IntTy );
174 FunctionType* exit_type =
175 FunctionType::get( Type::VoidTy, params, false );
176 TheExit = new Function(
177 exit_type, GlobalValue::ExternalLinkage, "exit", TheModule);
178
179 Constant* str_format = ConstantArray::get("%s");
180 StrFormat = new GlobalVariable(
181 /*type=*/ArrayType::get( Type::SByteTy, 3 ),
182 /*isConstant=*/true,
183 /*Linkage=*/GlobalValue::LinkOnceLinkage,
184 /*initializer=*/str_format,
185 /*name=*/"_str_format_",
186 /*parent=*/TheModule
187 );
188
189 Constant* in_str_format = ConstantArray::get(" %as");
190 InStrFormat = new GlobalVariable(
191 /*type=*/ArrayType::get( Type::SByteTy, 5 ),
192 /*isConstant=*/true,
193 /*Linkage=*/GlobalValue::LinkOnceLinkage,
194 /*initializer=*/in_str_format,
195 /*name=*/"_in_str_format_",
196 /*parent=*/TheModule
197 );
198
199 Constant* num_format = ConstantArray::get("%d");
200 NumFormat = new GlobalVariable(
201 /*type=*/ArrayType::get( Type::SByteTy, 3 ),
202 /*isConstant=*/true,
203 /*Linkage=*/GlobalValue::LinkOnceLinkage,
204 /*initializer=*/num_format,
205 /*name=*/"_num_format_",
206 /*parent=*/TheModule
207 );
208
209 Constant* in_num_format = ConstantArray::get(" %d");
210 InNumFormat = new GlobalVariable(
211 /*type=*/ArrayType::get( Type::SByteTy, 4 ),
212 /*isConstant=*/true,
213 /*Linkage=*/GlobalValue::LinkOnceLinkage,
214 /*initializer=*/in_num_format,
215 /*name=*/"_in_num_format_",
216 /*parent=*/TheModule
217 );
218
219 Constant* chr_format = ConstantArray::get("%c");
220 ChrFormat = new GlobalVariable(
221 /*type=*/ArrayType::get( Type::SByteTy, 3 ),
222 /*isConstant=*/true,
223 /*Linkage=*/GlobalValue::LinkOnceLinkage,
224 /*initializer=*/chr_format,
225 /*name=*/"_chr_format_",
226 /*parent=*/TheModule
227 );
228
229 Constant* in_chr_format = ConstantArray::get(" %c");
230 InChrFormat = new GlobalVariable(
231 /*type=*/ArrayType::get( Type::SByteTy, 4 ),
232 /*isConstant=*/true,
233 /*Linkage=*/GlobalValue::LinkOnceLinkage,
234 /*initializer=*/in_chr_format,
235 /*name=*/"_in_chr_format_",
236 /*parent=*/TheModule
237 );
238
239 // Get some constants so we aren't always creating them
240 Zero = ConstantInt::get( Type::LongTy, 0 );
241 One = ConstantInt::get( Type::LongTy, 1 );
242 Two = ConstantInt::get( Type::LongTy, 2 );
243 Three = ConstantInt::get( Type::LongTy, 3 );
244 Four = ConstantInt::get( Type::LongTy, 4 );
245 Five = ConstantInt::get( Type::LongTy, 5 );
246
247 // Reset the current line number
248 Stackerlineno = 1;
249
250 // Reset the parser's input to F
251 Stackerin = F; // Set the input file.
252
253 // Let the parse know about this instance
254 TheInstance = this;
255
256 // Parse the file. The parser (see StackParser.y) will call back to
257 // the StackerCompiler via the "handle*" methods
258 Stackerparse();
259
260 // Avoid potential illegal use (TheInstance might be on the stack)
261 TheInstance = 0;
126 // Create a type to represent the stack. This is the same as the LLVM
127 // Assembly type [ 256 x long ]
128 stack_type = ArrayType::get( Type::LongTy, stack_size );
129
130 // Create a global variable for the stack. Note the use of appending
131 // linkage linkage so that multiple modules will make the stack larger.
132 // Also note that the last argument causes the global to be inserted
133 // automatically into the module.
134 TheStack = new GlobalVariable(
135 /*type=*/ stack_type,
136 /*isConstant=*/ false,
137 /*Linkage=*/ GlobalValue::LinkOnceLinkage,
138 /*initializer=*/ Constant::getNullValue(stack_type),
139 /*name=*/ "_stack_",
140 /*parent=*/ TheModule
141 );
142
143 // Create a global variable for indexing into the stack. Note the use
144 // of LinkOnce linkage. Only one copy of _index_ will be retained
145 // after linking
146 TheIndex = new GlobalVariable(
147 /*type=*/Type::LongTy,
148 /*isConstant=*/false,
149 /*Linkage=*/GlobalValue::LinkOnceLinkage,
150 /*initializer=*/ Constant::getNullValue(Type::LongTy),
151 /*name=*/"_index_",
152 /*parent=*/TheModule
153 );
154
155 // Create a function prototype for definitions. No parameters, no
156 // result. This is used below any time a function is created.
157 std::vector params; // No parameters
158 DefinitionType = FunctionType::get( Type::VoidTy, params, false );
159
160 // Create a function for printf(3)
161 params.push_back( PointerType::get( Type::SByteTy ) );
162 FunctionType* printf_type =
163 FunctionType::get( Type::IntTy, params, true );
164 ThePrintf = new Function(
165 printf_type, GlobalValue::ExternalLinkage, "printf", TheModule);
166
167 // Create a function for scanf(3)
168 TheScanf = new Function(
169 printf_type, GlobalValue::ExternalLinkage, "scanf", TheModule);
170
171 // Create a function for exit(3)
172 params.clear();
173 params.push_back( Type::IntTy );
174 FunctionType* exit_type =
175 FunctionType::get( Type::VoidTy, params, false );
176 TheExit = new Function(
177 exit_type, GlobalValue::ExternalLinkage, "exit", TheModule);
178
179 Constant* str_format = ConstantArray::get("%s");
180 StrFormat = new GlobalVariable(
181 /*type=*/ArrayType::get( Type::SByteTy, 3 ),
182 /*isConstant=*/true,
183 /*Linkage=*/GlobalValue::LinkOnceLinkage,
184 /*initializer=*/str_format,
185 /*name=*/"_str_format_",
186 /*parent=*/TheModule
187 );
188
189 Constant* in_str_format = ConstantArray::get(" %as");
190 InStrFormat = new GlobalVariable(
191 /*type=*/ArrayType::get( Type::SByteTy, 5 ),
192 /*isConstant=*/true,
193 /*Linkage=*/GlobalValue::LinkOnceLinkage,
194 /*initializer=*/in_str_format,
195 /*name=*/"_in_str_format_",
196 /*parent=*/TheModule
197 );
198
199 Constant* num_format = ConstantArray::get("%d");
200 NumFormat = new GlobalVariable(
201 /*type=*/ArrayType::get( Type::SByteTy, 3 ),
202 /*isConstant=*/true,
203 /*Linkage=*/GlobalValue::LinkOnceLinkage,
204 /*initializer=*/num_format,
205 /*name=*/"_num_format_",
206 /*parent=*/TheModule
207 );
208
209 Constant* in_num_format = ConstantArray::get(" %d");
210 InNumFormat = new GlobalVariable(
211 /*type=*/ArrayType::get( Type::SByteTy, 4 ),
212 /*isConstant=*/true,
213 /*Linkage=*/GlobalValue::LinkOnceLinkage,
214 /*initializer=*/in_num_format,
215 /*name=*/"_in_num_format_",
216 /*parent=*/TheModule
217 );
218
219 Constant* chr_format = ConstantArray::get("%c");
220 ChrFormat = new GlobalVariable(
221 /*type=*/ArrayType::get( Type::SByteTy, 3 ),
222 /*isConstant=*/true,
223 /*Linkage=*/GlobalValue::LinkOnceLinkage,
224 /*initializer=*/chr_format,
225 /*name=*/"_chr_format_",
226 /*parent=*/TheModule
227 );
228
229 Constant* in_chr_format = ConstantArray::get(" %c");
230 InChrFormat = new GlobalVariable(
231 /*type=*/ArrayType::get( Type::SByteTy, 4 ),
232 /*isConstant=*/true,
233 /*Linkage=*/GlobalValue::LinkOnceLinkage,
234 /*initializer=*/in_chr_format,
235 /*name=*/"_in_chr_format_",
236 /*parent=*/TheModule
237 );
238
239 // Get some constants so we aren't always creating them
240 Zero = ConstantInt::get( Type::LongTy, 0 );
241 One = ConstantInt::get( Type::LongTy, 1 );
242 Two = ConstantInt::get( Type::LongTy, 2 );
243 Three = ConstantInt::get( Type::LongTy, 3 );
244 Four = ConstantInt::get( Type::LongTy, 4 );
245 Five = ConstantInt::get( Type::LongTy, 5 );
246
247 // Reset the current line number
248 Stackerlineno = 1;
249
250 // Reset the parser's input to F
251 Stackerin = F; // Set the input file.
252
253 // Let the parse know about this instance
254 TheInstance = this;
255
256 // Parse the file. The parser (see StackParser.y) will call back to
257 // the StackerCompiler via the "handle*" methods
258 Stackerparse();
259
260 // Avoid potential illegal use (TheInstance might be on the stack)
261 TheInstance = 0;
262262
263263 // Set up a pass manager
264264 PassManager Passes;
341341 Passes.run(*TheModule);
342342
343343 } catch (...) {
344 if (F != stdin) fclose(F); // Make sure to close file descriptor
345 throw; // if an exception is thrown
344 if (F != stdin) fclose(F); // Make sure to close file descriptor
345 throw; // if an exception is thrown
346346 }
347347
348348 // Close the file
369369 CastInst* caster = new CastInst( ival, Type::LongTy );
370370 bb->getInstList().push_back( caster );
371371 BinaryOperator* addop = BinaryOperator::create( Instruction::Add,
372 loadop, caster);
372 loadop, caster);
373373 bb->getInstList().push_back( addop );
374374
375375 // Store the incremented value
390390 CastInst* caster = new CastInst( ival, Type::LongTy );
391391 bb->getInstList().push_back( caster );
392392 BinaryOperator* subop = BinaryOperator::create( Instruction::Sub,
393 loadop, caster);
393 loadop, caster);
394394 bb->getInstList().push_back( subop );
395395
396396 // Store the incremented value
417417
418418 if ( index == 0 )
419419 {
420 indexVec.push_back(loadop);
420 indexVec.push_back(loadop);
421421 }
422422 else
423423 {
424 CastInst* caster = new CastInst( index, Type::LongTy );
425 bb->getInstList().push_back( caster );
426 BinaryOperator* subop = BinaryOperator::create(
427 Instruction::Sub, loadop, caster );
428 bb->getInstList().push_back( subop );
429 indexVec.push_back(subop);
424 CastInst* caster = new CastInst( index, Type::LongTy );
425 bb->getInstList().push_back( caster );
426 BinaryOperator* subop = BinaryOperator::create(
427 Instruction::Sub, loadop, caster );
428 bb->getInstList().push_back( subop );
429 indexVec.push_back(subop);
430430 }
431431
432432 // Get the address of the indexed stack element
433433 GetElementPtrInst* gep = new GetElementPtrInst( TheStack, indexVec );
434 bb->getInstList().push_back( gep ); // Put GEP in Block
434 bb->getInstList().push_back( gep ); // Put GEP in Block
435435
436436 return gep;
437437 }
444444
445445 // Get the stack pointer
446446 GetElementPtrInst* gep = cast(
447 get_stack_pointer( bb ) );
447 get_stack_pointer( bb ) );
448448
449449 // Cast the value to a long .. hopefully it works
450450 CastInst* cast_inst = new CastInst( val, Type::LongTy );
469469 {
470470 // Get the stack pointer
471471 GetElementPtrInst* gep = cast(
472 get_stack_pointer( bb ));
472 get_stack_pointer( bb ));
473473
474474 // Load the value
475475 LoadInst* load_inst = new LoadInst( gep );
497497
498498 // Create an internal linkage global variable to hold the constant.
499499 GlobalVariable* strconst = new GlobalVariable(
500 char_array,
501 /*isConstant=*/true,
502 GlobalValue::InternalLinkage,
503 /*initializer=*/initVal,
504 "",
505 TheModule
500 char_array,
501 /*isConstant=*/true,
502 GlobalValue::InternalLinkage,
503 /*initializer=*/initVal,
504 "",
505 TheModule
506506 );
507507
508508 // Push the casted value
514514 {
515515 // Get location of stack pointer
516516 GetElementPtrInst* gep = cast(
517 get_stack_pointer( bb ));
517 get_stack_pointer( bb ));
518518
519519 // Load the value from the stack
520520 LoadInst* loader = new LoadInst( gep );
536536 {
537537 // Get the stack pointer
538538 GetElementPtrInst* gep = cast(
539 get_stack_pointer( bb, index ));
539 get_stack_pointer( bb, index ));
540540
541541 // Store the value there
542542 StoreInst* store_inst = new StoreInst( new_top, gep );
551551 {
552552 // Get the stack pointer
553553 GetElementPtrInst* gep = cast(
554 get_stack_pointer( bb, index ));
554 get_stack_pointer( bb, index ));
555555
556556 // Load the value
557557 LoadInst* load_inst = new LoadInst( gep );
566566 {
567567 // Get location of stack pointer
568568 GetElementPtrInst* gep = cast(
569 get_stack_pointer( bb, index ));
569 get_stack_pointer( bb, index ));
570570
571571 // Load the value from the stack
572572 LoadInst* loader = new LoadInst( gep );
585585 {
586586 if ( ! f->empty() && f->back().getTerminator() == 0 )
587587 {
588 BranchInst* branch = new BranchInst(bb);
589 f->back().getInstList().push_back( branch );
588 BranchInst* branch = new BranchInst(bb);
589 f->back().getInstList().push_back( branch );
590590 }
591591 f->getBasicBlockList().push_back( bb );
592592 }
621621 {
622622 if ( ! definition->empty() )
623623 {
624 BasicBlock& last_block = definition->back();
625 if ( last_block.getTerminator() == 0 )
626 {
627 last_block.getInstList().push_back( new ReturnInst() );
628 }
624 BasicBlock& last_block = definition->back();
625 if ( last_block.getTerminator() == 0 )
626 {
627 last_block.getInstList().push_back( new ReturnInst() );
628 }
629629 }
630630 // Insert the definition into the module
631631 mod->getFunctionList().push_back( definition );
660660 {
661661 // Just create a placeholder function
662662 Function* the_function = new Function (
663 DefinitionType,
664 GlobalValue::ExternalLinkage,
665 name );
663 DefinitionType,
664 GlobalValue::ExternalLinkage,
665 name );
666666 assert( the_function->isExternal() );
667667
668668 free( name );
680680 // If the function already exists...
681681 if ( existing_function )
682682 {
683 // Just get rid of the placeholder
684 existing_function->dropAllReferences();
685 delete existing_function;
683 // Just get rid of the placeholder
684 existing_function->dropAllReferences();
685 delete existing_function;
686686 }
687687 #endif
688688
719719
720720 // Compare the condition against 0
721721 SetCondInst* cond_inst = new SetCondInst( Instruction::SetNE, cond,
722 ConstantSInt::get( Type::LongTy, 0) );
722 ConstantSInt::get( Type::LongTy, 0) );
723723 bb->getInstList().push_back( cond_inst );
724724
725725 // Create an exit block
734734
735735 // Create a branch on the SetCond
736736 BranchInst* br_inst = new BranchInst( true_bb,
737 ( ifFalse ? false_bb : exit_bb ), cond_inst );
737 ( ifFalse ? false_bb : exit_bb ), cond_inst );
738738 bb->getInstList().push_back( br_inst );
739739
740740 // Fill the true block
741741 std::vector args;
742742 if ( Function* true_func = TheModule->getNamedFunction(ifTrue) )
743743 {
744 true_bb->getInstList().push_back(
745 new CallInst( true_func, args ) );
746 true_bb->getInstList().push_back(
747 new BranchInst( exit_bb ) );
744 true_bb->getInstList().push_back(
745 new CallInst( true_func, args ) );
746 true_bb->getInstList().push_back(
747 new BranchInst( exit_bb ) );
748748 }
749749 else
750750 {
751 ThrowException(std::string("Function '") + ifTrue +
752 "' must be declared first.'");
751 ThrowException(std::string("Function '") + ifTrue +
752 "' must be declared first.'");
753753 }
754754
755755 free( ifTrue );
757757 // Fill the false block
758758 if ( false_bb )
759759 {
760 if ( Function* false_func = TheModule->getNamedFunction(ifFalse) )
761 {
762 false_bb->getInstList().push_back(
763 new CallInst( false_func, args ) );
764 false_bb->getInstList().push_back(
765 new BranchInst( exit_bb ) );
766 }
767 else
768 {
769 ThrowException(std::string("Function '") + ifFalse +
770 "' must be declared first.'");
771 }
772 free( ifFalse );
760 if ( Function* false_func = TheModule->getNamedFunction(ifFalse) )
761 {
762 false_bb->getInstList().push_back(
763 new CallInst( false_func, args ) );
764 false_bb->getInstList().push_back(
765 new BranchInst( exit_bb ) );
766 }
767 else
768 {
769 ThrowException(std::string("Function '") + ifFalse +
770 "' must be declared first.'");
771 }
772 free( ifFalse );
773773 }
774774
775775 // Add the blocks to the function
803803
804804 // Compare the condition against 0
805805 SetCondInst* cond_inst = new SetCondInst(
806 Instruction::SetNE, cond, ConstantSInt::get( Type::LongTy, 0) );
806 Instruction::SetNE, cond, ConstantSInt::get( Type::LongTy, 0) );
807807 test->getInstList().push_back( cond_inst );
808808
809809 // Add the branch instruction
814814 std::vector args;
815815 if ( Function* body_func = TheModule->getNamedFunction(todo) )
816816 {
817 body->getInstList().push_back( new CallInst( body_func, args ) );
818 body->getInstList().push_back( new BranchInst( test ) );
817 body->getInstList().push_back( new CallInst( body_func, args ) );
818 body->getInstList().push_back( new BranchInst( test ) );
819819 }
820820 else
821821 {
822 ThrowException(std::string("Function '") + todo +
823 "' must be declared first.'");
822 ThrowException(std::string("Function '") + todo +
823 "' must be declared first.'");
824824 }
825825
826826 free( todo );
840840 BasicBlock* bb = new BasicBlock((echo?"call":""));
841841 if ( func )
842842 {
843 CallInst* call_def = new CallInst( func , no_arguments );
844 bb->getInstList().push_back( call_def );
843 CallInst* call_def = new CallInst( func , no_arguments );
844 bb->getInstList().push_back( call_def );
845845 }
846846 else
847847 {
848 ThrowException(std::string("Definition '") + name +
849 "' must be defined before it can be used.");
848 ThrowException(std::string("Definition '") + name +
849 "' must be defined before it can be used.");
850850 }
851851
852852 free( name );
891891 {
892892 case DUMP : // Dump the stack (debugging aid)
893893 {
894 if (echo) bb->setName("DUMP");
895 Function* f = TheModule->getOrInsertFunction(
896 "_stacker_dump_stack_", DefinitionType);
897 std::vector args;
898 bb->getInstList().push_back( new CallInst( f, args ) );
899 break;
894 if (echo) bb->setName("DUMP");
895 Function* f = TheModule->getOrInsertFunction(
896 "_stacker_dump_stack_", DefinitionType);
897 std::vector args;
898 bb->getInstList().push_back( new CallInst( f, args ) );
899 break;
900900 }
901901
902902 // Logical Operations
903903 case TRUETOK : // -- -1
904904 {
905 if (echo) bb->setName("TRUE");
906 push_integer(bb,-1);
907 break;
905 if (echo) bb->setName("TRUE");
906 push_integer(bb,-1);
907 break;
908908 }
909909 case FALSETOK : // -- 0
910910 {
911 if (echo) bb->setName("FALSE");
912 push_integer(bb,0);
913 break;
911 if (echo) bb->setName("FALSE");
912 push_integer(bb,0);
913 break;
914914 }
915915 case LESS : // w1 w2 -- w2
916916 {
917 if (echo) bb->setName("LESS");
918 LoadInst* op1 = cast(pop_integer(bb));
919 LoadInst* op2 = cast(pop_integer(bb));
920 SetCondInst* cond_inst =
921 new SetCondInst( Instruction::SetLT, op1, op2 );
922 bb->getInstList().push_back( cond_inst );
923 push_value( bb, cond_inst );
924 break;
917 if (echo) bb->setName("LESS");
918 LoadInst* op1 = cast(pop_integer(bb));
919 LoadInst* op2 = cast(pop_integer(bb));
920 SetCondInst* cond_inst =
921 new SetCondInst( Instruction::SetLT, op1, op2 );
922 bb->getInstList().push_back( cond_inst );
923 push_value( bb, cond_inst );
924 break;
925925 }
926926 case MORE : // w1 w2 -- w2>w1
927927 {
928 if (echo) bb->setName("MORE");
929 LoadInst* op1 = cast(pop_integer(bb));
930 LoadInst* op2 = cast(pop_integer(bb));
931 SetCondInst* cond_inst =
932 new SetCondInst( Instruction::SetGT, op1, op2 );
933 bb->getInstList().push_back( cond_inst );
934 push_value( bb, cond_inst );
935 break;
928 if (echo) bb->setName("MORE");
929 LoadInst* op1 = cast(pop_integer(bb));
930 LoadInst* op2 = cast(pop_integer(bb));
931 SetCondInst* cond_inst =
932 new SetCondInst( Instruction::SetGT, op1, op2 );
933 bb->getInstList().push_back( cond_inst );
934 push_value( bb, cond_inst );
935 break;
936936 }
937937 case LESS_EQUAL : // w1 w2 -- w2<=w1
938938 {
939 if (echo) bb->setName("LE");
940 LoadInst* op1 = cast(pop_integer(bb));
941 LoadInst* op2 = cast(pop_integer(bb));
942 SetCondInst* cond_inst =
943 new SetCondInst( Instruction::SetLE, op1, op2 );
944 bb->getInstList().push_back( cond_inst );
945 push_value( bb, cond_inst );
946 break;
939 if (echo) bb->setName("LE");
940 LoadInst* op1 = cast(pop_integer(bb));
941 LoadInst* op2 = cast(pop_integer(bb));
942 SetCondInst* cond_inst =
943 new SetCondInst( Instruction::SetLE, op1, op2 );
944 bb->getInstList().push_back( cond_inst );
945 push_value( bb, cond_inst );
946 break;
947947 }
948948 case MORE_EQUAL : // w1 w2 -- w2>=w1
949949 {
950 if (echo) bb->setName("GE");
951 LoadInst* op1 = cast(pop_integer(bb));
952 LoadInst* op2 = cast(pop_integer(bb));
953 SetCondInst* cond_inst =
954 new SetCondInst( Instruction::SetGE, op1, op2 );
955 bb->getInstList().push_back( cond_inst );
956 push_value( bb, cond_inst );
957 break;
950 if (echo) bb->setName("GE");
951 LoadInst* op1 = cast(pop_integer(bb));
952 LoadInst* op2 = cast(pop_integer(bb));
953 SetCondInst* cond_inst =
954 new SetCondInst( Instruction::SetGE, op1, op2 );
955 bb->getInstList().push_back( cond_inst );
956 push_value( bb, cond_inst );
957 break;
958958 }
959959 case NOT_EQUAL : // w1 w2 -- w2!=w1
960960 {
961 if (echo) bb->setName("NE");
962 LoadInst* op1 = cast(pop_integer(bb));
963 LoadInst* op2 = cast(pop_integer(bb));
964 SetCondInst* cond_inst =
965 new SetCondInst( Instruction::SetNE, op1, op2 );
966 bb->getInstList().push_back( cond_inst );
967 push_value( bb, cond_inst );
968 break;
961 if (echo) bb->setName("NE");
962 LoadInst* op1 = cast(pop_integer(bb));
963 LoadInst* op2 = cast(pop_integer(bb));
964 SetCondInst* cond_inst =
965 new SetCondInst( Instruction::SetNE, op1, op2 );
966 bb->getInstList().push_back( cond_inst );
967 push_value( bb, cond_inst );
968 break;
969969 }
970970 case EQUAL : // w1 w2 -- w1==w2
971971 {
972 if (echo) bb->setName("EQ");
973 LoadInst* op1 = cast(pop_integer(bb));
974 LoadInst* op2 = cast(pop_integer(bb));
975 SetCondInst* cond_inst =
976 new SetCondInst( Instruction::SetEQ, op1, op2 );
977 bb->getInstList().push_back( cond_inst );
978 push_value( bb, cond_inst );
979 break;
972 if (echo) bb->setName("EQ");
973 LoadInst* op1 = cast(pop_integer(bb));
974 LoadInst* op2 = cast(pop_integer(bb));
975 SetCondInst* cond_inst =
976 new SetCondInst( Instruction::SetEQ, op1, op2 );
977 bb->getInstList().push_back( cond_inst );
978 push_value( bb, cond_inst );
979 break;
980980 }
981981
982982 // Arithmetic Operations
983983 case PLUS : // w1 w2 -- w2+w1
984984 {
985 if (echo) bb->setName("ADD");
986 LoadInst* op1 = cast(pop_integer(bb));
987 LoadInst* op2 = cast(pop_integer(bb));
988 BinaryOperator* addop =
989 BinaryOperator::create( Instruction::Add, op1, op2);
990 bb->getInstList().push_back( addop );
991 push_value( bb, addop );
992 break;
985 if (echo) bb->setName("ADD");
986 LoadInst* op1 = cast(pop_integer(bb));
987 LoadInst* op2 = cast(pop_integer(bb));
988 BinaryOperator* addop =
989 BinaryOperator::create( Instruction::Add, op1, op2);
990 bb->getInstList().push_back( addop );
991 push_value( bb, addop );
992 break;
993993 }
994994 case MINUS : // w1 w2 -- w2-w1
995995 {
996 if (echo) bb->setName("SUB");
997 LoadInst* op1 = cast(pop_integer(bb));
998 LoadInst* op2 = cast(pop_integer(bb));
999 BinaryOperator* subop =
1000 BinaryOperator::create( Instruction::Sub, op1, op2);
1001 bb->getInstList().push_back( subop );
1002 push_value( bb, subop );
1003 break;
996 if (echo) bb->setName("SUB");
997 LoadInst* op1 = cast(pop_integer(bb));
998 LoadInst* op2 = cast(pop_integer(bb));
999 BinaryOperator* subop =
1000 BinaryOperator::create( Instruction::Sub, op1, op2);
1001 bb->getInstList().push_back( subop );
1002 push_value( bb, subop );
1003 break;
10041004 }
10051005 case INCR : // w1 -- w1+1
10061006 {
1007 if (echo) bb->setName("INCR");
1008 LoadInst* op1 = cast(pop_integer(bb));
1009 BinaryOperator* addop =
1010 BinaryOperator::create( Instruction::Add, op1, One );
1011 bb->getInstList().push_back( addop );
1012 push_value( bb, addop );
1013 break;
1007 if (echo) bb->setName("INCR");
1008 LoadInst* op1 = cast(pop_integer(bb));
1009 BinaryOperator* addop =
1010 BinaryOperator::create( Instruction::Add, op1, One );
1011 bb->getInstList().push_back( addop );
1012 push_value( bb, addop );
1013 break;
10141014 }
10151015 case DECR : // w1 -- w1-1
10161016 {
1017 if (echo) bb->setName("DECR");
1018 LoadInst* op1 = cast(pop_integer(bb));
1019 BinaryOperator* subop = BinaryOperator::create( Instruction::Sub, op1,
1020 ConstantSInt::get( Type::LongTy, 1 ) );
1021 bb->getInstList().push_back( subop );
1022 push_value( bb, subop );
1023 break;
1017 if (echo) bb->setName("DECR");
1018 LoadInst* op1 = cast(pop_integer(bb));
1019 BinaryOperator* subop = BinaryOperator::create( Instruction::Sub, op1,
1020 ConstantSInt::get( Type::LongTy, 1 ) );
1021 bb->getInstList().push_back( subop );
1022 push_value( bb, subop );
1023 break;
10241024 }
10251025 case MULT : // w1 w2 -- w2*w1
10261026 {
1027 if (echo) bb->setName("MUL");
1028 LoadInst* op1 = cast(pop_integer(bb));
1029 LoadInst* op2 = cast(pop_integer(bb));
1030 BinaryOperator* multop =
1031 BinaryOperator::create( Instruction::Mul, op1, op2);
1032 bb->getInstList().push_back( multop );
1033 push_value( bb, multop );
1034 break;
1027 if (echo) bb->setName("MUL");
1028 LoadInst* op1 = cast(pop_integer(bb));
1029 LoadInst* op2 = cast(pop_integer(bb));
1030 BinaryOperator* multop =
1031 BinaryOperator::create( Instruction::Mul, op1, op2);
1032 bb->getInstList().push_back( multop );
1033 push_value( bb, multop );
1034 break;
10351035 }
10361036 case DIV :// w1 w2 -- w2/w1
10371037 {
1038 if (echo) bb->setName("DIV");
1039 LoadInst* op1 = cast(pop_integer(bb));
1040 LoadInst* op2 = cast(pop_integer(bb));
1041 BinaryOperator* divop =
1042 BinaryOperator::create( Instruction::Div, op1, op2);
1043 bb->getInstList().push_back( divop );
1044 push_value( bb, divop );
1045 break;
1038 if (echo) bb->setName("DIV");
1039 LoadInst* op1 = cast(pop_integer(bb));
1040 LoadInst* op2 = cast(pop_integer(bb));
1041 BinaryOperator* divop =
1042 BinaryOperator::create( Instruction::Div, op1, op2);
1043 bb->getInstList().push_back( divop );
1044 push_value( bb, divop );
1045 break;
10461046 }
10471047 case MODULUS : // w1 w2 -- w2%w1
10481048 {
1049 if (echo) bb->setName("MOD");
1050 LoadInst* op1 = cast(pop_integer(bb));
1051 LoadInst* op2 = cast(pop_integer(bb));
1052 BinaryOperator* divop =
1053 BinaryOperator::create( Instruction::Rem, op1, op2);
1054 bb->getInstList().push_back( divop );
1055 push_value( bb, divop );
1056 break;
1049 if (echo) bb->setName("MOD");
1050 LoadInst* op1 = cast(pop_integer(bb));
1051 LoadInst* op2 = cast(pop_integer(bb));
1052 BinaryOperator* divop =
1053 BinaryOperator::create( Instruction::Rem, op1, op2);
1054 bb->getInstList().push_back( divop );
1055 push_value( bb, divop );
1056 break;
10571057 }
10581058 case STAR_SLASH : // w1 w2 w3 -- (w3*w2)/w1
10591059 {
1060 if (echo) bb->setName("STAR_SLASH");
1061 // Get the operands
1062 LoadInst* op1 = cast(pop_integer(bb));
1063 LoadInst* op2 = cast(pop_integer(bb));
1064 LoadInst* op3 = cast(pop_integer(bb));
1065
1066 // Multiply the first two
1067 BinaryOperator* multop =
1068 BinaryOperator::create( Instruction::Mul, op1, op2);
1069 bb->getInstList().push_back( multop );
1070
1071 // Divide by the third operand
1072 BinaryOperator* divop =
1073 BinaryOperator::create( Instruction::Div, multop, op3);
1074 bb->getInstList().push_back( divop );
1075
1076 // Push the result
1077 push_value( bb, divop );
1078
1079 break;
1060 if (echo) bb->setName("STAR_SLASH");
1061 // Get the operands
1062 LoadInst* op1 = cast(pop_integer(bb));
1063 LoadInst* op2 = cast(pop_integer(bb));
1064 LoadInst* op3 = cast(pop_integer(bb));
1065
1066 // Multiply the first two
1067 BinaryOperator* multop =
1068 BinaryOperator::create( Instruction::Mul, op1, op2);
1069 bb->getInstList().push_back( multop );
1070
1071 // Divide by the third operand
1072 BinaryOperator* divop =
1073 BinaryOperator::create( Instruction::Div, multop, op3);
1074 bb->getInstList().push_back( divop );
1075
1076 // Push the result
1077 push_value( bb, divop );
1078
1079 break;
10801080 }
10811081 case NEGATE : // w1 -- -w1
10821082 {
1083 if (echo) bb->setName("NEG");
1084 LoadInst* op1 = cast(pop_integer(bb));
1085 // APPARENTLY, the following doesn't work:
1086 // BinaryOperator* negop = BinaryOperator::createNeg( op1 );
1087 // bb->getInstList().push_back( negop );
1088 // So we'll multiply by -1 (ugh)
1089 BinaryOperator* multop = BinaryOperator::create( Instruction::Mul, op1,
1090 ConstantSInt::get( Type::LongTy, -1 ) );
1091 bb->getInstList().push_back( multop );
1092 push_value( bb, multop );
1093 break;
1083 if (echo) bb->setName("NEG");
1084 LoadInst* op1 = cast(pop_integer(bb));
1085 // APPARENTLY, the following doesn't work:
1086 // BinaryOperator* negop = BinaryOperator::createNeg( op1 );
1087 // bb->getInstList().push_back( negop );
1088 // So we'll multiply by -1 (ugh)
1089 BinaryOperator* multop = BinaryOperator::create( Instruction::Mul, op1,
1090 ConstantSInt::get( Type::LongTy, -1 ) );
1091 bb->getInstList().push_back( multop );
1092 push_value( bb, multop );
1093 break;
10941094 }
10951095 case ABS : // w1 -- |w1|
10961096 {
1097 if (echo) bb->setName("ABS");
1098 // Get the top of stack value
1099 LoadInst* op1 = cast(stack_top(bb));
1100
1101 // Determine if its negative
1102 SetCondInst* cond_inst =
1103 new SetCondInst( Instruction::SetLT, op1, Zero );
1104 bb->getInstList().push_back( cond_inst );
1105
1106 // Create a block for storing the result
1107 BasicBlock* exit_bb = new BasicBlock((echo?"exit":""));
1108
1109 // Create a block for making it a positive value
1110 BasicBlock* pos_bb = new BasicBlock((echo?"neg":""));
1111
1112 // Create the branch on the SetCond
1113 BranchInst* br_inst = new BranchInst( pos_bb, exit_bb, cond_inst );
1114 bb->getInstList().push_back( br_inst );
1115
1116 // Fill out the negation block
1117 LoadInst* pop_op = cast( pop_integer(pos_bb) );
1118 BinaryOperator* neg_op = BinaryOperator::createNeg( pop_op );
1119 pos_bb->getInstList().push_back( neg_op );
1120 push_value( pos_bb, neg_op );
1121 pos_bb->getInstList().push_back( new BranchInst( exit_bb ) );
1122
1123 // Add the new blocks in the correct order
1124 add_block( TheFunction, bb );
1125 add_block( TheFunction, pos_bb );
1126 bb = exit_bb;
1127 break;
1097 if (echo) bb->setName("ABS");
1098 // Get the top of stack value
1099 LoadInst* op1 = cast(stack_top(bb));
1100
1101 // Determine if its negative
1102 SetCondInst* cond_inst =
1103 new SetCondInst( Instruction::SetLT, op1, Zero );
1104 bb->getInstList().push_back( cond_inst );
1105
1106 // Create a block for storing the result
1107 BasicBlock* exit_bb = new BasicBlock((echo?"exit":""));
1108
1109 // Create a block for making it a positive value
1110 BasicBlock* pos_bb = new BasicBlock((echo?"neg":""));
1111
1112 // Create the branch on the SetCond
1113 BranchInst* br_inst = new BranchInst( pos_bb, exit_bb, cond_inst );
1114 bb->getInstList().push_back( br_inst );
1115
1116 // Fill out the negation block
1117 LoadInst* pop_op = cast( pop_integer(pos_bb) );
1118 BinaryOperator* neg_op = BinaryOperator::createNeg( pop_op );
1119 pos_bb->getInstList().push_back( neg_op );
1120 push_value( pos_bb, neg_op );
1121 pos_bb->getInstList().push_back( new BranchInst( exit_bb ) );
1122
1123 // Add the new blocks in the correct order
1124 add_block( TheFunction, bb );
1125 add_block( TheFunction, pos_bb );
1126 bb = exit_bb;
1127 break;
11281128 }
11291129 case MIN : // w1 w2 -- (w2
11301130 {
1131 if (echo) bb->setName("MIN");
1132
1133 // Create the three blocks
1134 BasicBlock* exit_bb = new BasicBlock((echo?"exit":""));
1135 BasicBlock* op1_block = new BasicBlock((echo?"less":""));
1136 BasicBlock* op2_block = new BasicBlock((echo?"more":""));
1137
1138 // Get the two operands
1139 LoadInst* op1 = cast(pop_integer(bb));
1140 LoadInst* op2 = cast(pop_integer(bb));
1141
1142 // Compare them
1143 SetCondInst* cond_inst =
1144 new SetCondInst( Instruction::SetLT, op1, op2);
1145 bb->getInstList().push_back( cond_inst );
1146
1147 // Create a branch on the SetCond
1148 BranchInst* br_inst =
1149 new BranchInst( op1_block, op2_block, cond_inst );
1150 bb->getInstList().push_back( br_inst );
1151
1152 // Create a block for pushing the first one
1153 push_value(op1_block, op1);
1154 op1_block->getInstList().push_back( new BranchInst( exit_bb ) );
1155
1156 // Create a block for pushing the second one
1157 push_value(op2_block, op2);
1158 op2_block->getInstList().push_back( new BranchInst( exit_bb ) );
1159
1160 // Add the blocks
1161 add_block( TheFunction, bb );
1162 add_block( TheFunction, op1_block );
1163 add_block( TheFunction, op2_block );
1164 bb = exit_bb;
1165 break;
1131 if (echo) bb->setName("MIN");
1132
1133 // Create the three blocks
1134 BasicBlock* exit_bb = new BasicBlock((echo?"exit":""));
1135 BasicBlock* op1_block = new BasicBlock((echo?"less":""));
1136 BasicBlock* op2_block = new BasicBlock((echo?"more":""));
1137
1138 // Get the two operands
1139 LoadInst* op1 = cast(pop_integer(bb));
1140 LoadInst* op2 = cast(pop_integer(bb));
1141
1142 // Compare them
1143 SetCondInst* cond_inst =
1144 new SetCondInst( Instruction::SetLT, op1, op2);
1145 bb->getInstList().push_back( cond_inst );
1146
1147 // Create a branch on the SetCond
1148 BranchInst* br_inst =
1149 new BranchInst( op1_block, op2_block, cond_inst );
1150 bb->getInstList().push_back( br_inst );
1151
1152 // Create a block for pushing the first one
1153 push_value(op1_block, op1);
1154 op1_block->getInstList().push_back( new BranchInst( exit_bb ) );
1155
1156 // Create a block for pushing the second one
1157 push_value(op2_block, op2);
1158 op2_block->getInstList().push_back( new BranchInst( exit_bb ) );
1159
1160 // Add the blocks
1161 add_block( TheFunction, bb );
1162 add_block( TheFunction, op1_block );
1163 add_block( TheFunction, op2_block );
1164 bb = exit_bb;
1165 break;
11661166 }
11671167 case MAX : // w1 w2 -- (w2>w1?w2:w1)
11681168 {
1169 if (echo) bb->setName("MAX");
1170 // Get the two operands
1171 LoadInst* op1 = cast(pop_integer(bb));
1172 LoadInst* op2 = cast(pop_integer(bb));
1173
1174 // Compare them
1175 SetCondInst* cond_inst =
1176 new SetCondInst( Instruction::SetGT, op1, op2);
1177 bb->getInstList().push_back( cond_inst );
1178
1179 // Create an exit block
1180 BasicBlock* exit_bb = new BasicBlock((echo?"exit":""));
1181
1182 // Create a block for pushing the larger one
1183 BasicBlock* op1_block = new BasicBlock((echo?"more":""));
1184 push_value(op1_block, op1);
1185 op1_block->getInstList().push_back( new BranchInst( exit_bb ) );
1186
1187 // Create a block for pushing the smaller or equal one
1188 BasicBlock* op2_block = new BasicBlock((echo?"less":""));
1189 push_value(op2_block, op2);
1190 op2_block->getInstList().push_back( new BranchInst( exit_bb ) );
1191
1192 // Create a banch on the SetCond
1193 BranchInst* br_inst =
1194 new BranchInst( op1_block, op2_block, cond_inst );
1195 bb->getInstList().push_back( br_inst );
1196
1197 // Add the blocks
1198 add_block( TheFunction, bb );
1199 add_block( TheFunction, op1_block );
1200 add_block( TheFunction, op2_block );
1201
1202 bb = exit_bb;
1203 break;
1169 if (echo) bb->setName("MAX");
1170 // Get the two operands
1171 LoadInst* op1 = cast(pop_integer(bb));
1172 LoadInst* op2 = cast(pop_integer(bb));
1173
1174 // Compare them
1175 SetCondInst* cond_inst =
1176 new SetCondInst( Instruction::SetGT, op1, op2);
1177 bb->getInstList().push_back( cond_inst );
1178
1179 // Create an exit block
1180 BasicBlock* exit_bb = new BasicBlock((echo?"exit":""));
1181
1182 // Create a block for pushing the larger one
1183 BasicBlock* op1_block = new BasicBlock((echo?"more":""));
1184 push_value(op1_block, op1);
1185 op1_block->getInstList().push_back( new BranchInst( exit_bb ) );
1186
1187 // Create a block for pushing the smaller or equal one
1188 BasicBlock* op2_block = new BasicBlock((echo?"less":""));
1189 push_value(op2_block, op2);
1190 op2_block->getInstList().push_back( new BranchInst( exit_bb ) );
1191
1192 // Create a banch on the SetCond
1193 BranchInst* br_inst =
1194 new BranchInst( op1_block, op2_block, cond_inst );
1195 bb->getInstList().push_back( br_inst );
1196
1197 // Add the blocks
1198 add_block( TheFunction, bb );
1199 add_block( TheFunction, op1_block );
1200 add_block( TheFunction, op2_block );
1201
1202 bb = exit_bb;
1203 break;
12041204 }
12051205
12061206 // Bitwise Operators
12071207 case AND : // w1 w2 -- w2&w1
12081208 {
1209 if (echo) bb->setName("AND");
1210 LoadInst* op1 = cast(pop_integer(bb));
1211 LoadInst* op2 = cast(pop_integer(bb));
1212 BinaryOperator* andop =
1213 BinaryOperator::create( Instruction::And, op1, op2);
1214 bb->getInstList().push_back( andop );
1215 push_value( bb, andop );
1216 break;
1209 if (echo) bb->setName("AND");
1210 LoadInst* op1 = cast(pop_integer(bb));
1211 LoadInst* op2 = cast(pop_integer(bb));
1212 BinaryOperator* andop =
1213 BinaryOperator::create( Instruction::And, op1, op2);
1214 bb->getInstList().push_back( andop );
1215 push_value( bb, andop );
1216 break;
12171217 }
12181218 case OR : // w1 w2 -- w2|w1
12191219 {
1220 if (echo) bb->setName("OR");
1221 LoadInst* op1 = cast(pop_integer(bb));
1222 LoadInst* op2 = cast(pop_integer(bb));
1223 BinaryOperator* orop =
1224 BinaryOperator::create( Instruction::Or, op1, op2);
1225 bb->getInstList().push_back( orop );
1226 push_value( bb, orop );
1227 break;
1220 if (echo) bb->setName("OR");
1221 LoadInst* op1 = cast(pop_integer(bb));
1222 LoadInst* op2 = cast(pop_integer(bb));
1223 BinaryOperator* orop =
1224 BinaryOperator::create( Instruction::Or, op1, op2);
1225 bb->getInstList().push_back( orop );
1226 push_value( bb, orop );
1227 break;
12281228 }
12291229 case XOR : // w1 w2 -- w2^w1
12301230 {
1231 if (echo) bb->setName("XOR");
1232 LoadInst* op1 = cast(pop_integer(bb));
1233 LoadInst* op2 = cast(pop_integer(bb));
1234 BinaryOperator* xorop =
1235 BinaryOperator::create( Instruction::Xor, op1, op2);
1236 bb->getInstList().push_back( xorop );
1237 push_value( bb, xorop );
1238 break;
1231 if (echo) bb->setName("XOR");
1232 LoadInst* op1 = cast(pop_integer(bb));
1233 LoadInst* op2 = cast(pop_integer(bb));
1234 BinaryOperator* xorop =
1235 BinaryOperator::create( Instruction::Xor, op1, op2);
1236 bb->getInstList().push_back( xorop );
1237 push_value( bb, xorop );
1238 break;
12391239 }
12401240 case LSHIFT : // w1 w2 -- w1<
12411241 {
1242 if (echo) bb->setName("SHL");
1243 LoadInst* op1 = cast(pop_integer(bb));
1244 LoadInst* op2 = cast(pop_integer(bb));
1245 CastInst* castop = new CastInst( op1, Type::UByteTy );
1246 bb->getInstList().push_back( castop );
1247 ShiftInst* shlop = new ShiftInst( Instruction::Shl, op2, castop );
1248 bb->getInstList().push_back( shlop );
1249 push_value( bb, shlop );
1250 break;
1242 if (echo) bb->setName("SHL");
1243 LoadInst* op1 = cast(pop_integer(bb));
1244 LoadInst* op2 = cast(pop_integer(bb));
1245 CastInst* castop = new CastInst( op1, Type::UByteTy );
1246 bb->getInstList().push_back( castop );
1247 ShiftInst* shlop = new ShiftInst( Instruction::Shl, op2, castop );
1248 bb->getInstList().push_back( shlop );
1249 push_value( bb, shlop );
1250 break;
12511251 }
12521252 case RSHIFT : // w1 w2 -- w1>>w2
12531253 {
1254 if (echo) bb->setName("SHR");
1255 LoadInst* op1 = cast(pop_integer(bb));
1256 LoadInst* op2 = cast(pop_integer(bb));
1257 CastInst* castop = new CastInst( op1, Type::UByteTy );
1258 bb->getInstList().push_back( castop );
1259 ShiftInst* shrop = new ShiftInst( Instruction::Shr, op2, castop );
1260 bb->getInstList().push_back( shrop );
1261 push_value( bb, shrop );
1262 break;
1254 if (echo) bb->setName("SHR");
1255 LoadInst* op1 = cast(pop_integer(bb));
1256 LoadInst* op2 = cast(pop_integer(bb));
1257 CastInst* castop = new CastInst( op1, Type::UByteTy );
1258 bb->getInstList().push_back( castop );
1259 ShiftInst* shrop = new ShiftInst( Instruction::Shr, op2, castop );
1260 bb->getInstList().push_back( shrop );
1261 push_value( bb, shrop );
1262 break;
12631263 }
12641264
12651265 // Stack Manipulation Operations
1266 case DROP: // w --
1267 {
1268 if (echo) bb->setName("DROP");
1269 decr_stack_index(bb, One);
1270 break;
1271 }
1272 case DROP2: // w1 w2 --
1273 {
1274 if (echo) bb->setName("DROP2");
1275 decr_stack_index( bb, Two );
1276 break;
1277 }
1278 case NIP: // w1 w2 -- w2
1279 {
1280 if (echo) bb->setName("NIP");
1281 LoadInst* w2 = cast( stack_top( bb ) );
1282 decr_stack_index( bb );
1283 replace_top( bb, w2 );
1284 break;
1285 }
1286 case NIP2: // w1 w2 w3 w4 -- w3 w4
1287 {
1288 if (echo) bb->setName("NIP2");
1289 LoadInst* w4 = cast( stack_top( bb ) );
1290 LoadInst* w3 = cast( stack_top( bb, One ) );
1291 decr_stack_index( bb, Two );
1292 replace_top( bb, w4 );
1293 replace_top( bb, w3, One );
1294 break;
1295 }
1296 case DUP: // w -- w w
1297 {
1298 if (echo) bb->setName("DUP");
1299 LoadInst* w = cast( stack_top( bb ) );
1300 push_value( bb, w );
1301 break;
1302 }
1303 case DUP2: // w1 w2 -- w1 w2 w1 w2
1304 {
1305 if (echo) bb->setName("DUP2");
1306 LoadInst* w2 = cast( stack_top(bb) );
1307 LoadInst* w1 = cast( stack_top(bb, One ) );
1308 incr_stack_index( bb, Two );
1309 replace_top( bb, w1, One );
1310 replace_top( bb, w2 );
1311 break;
1312 }
1313 case SWAP: // w1 w2 -- w2 w1
1314 {
1315 if (echo) bb->setName("SWAP");
1316 LoadInst* w2 = cast( stack_top( bb ) );
1317 LoadInst* w1 = cast( stack_top( bb, One ) );
1318 replace_top( bb, w1 );
1319 replace_top( bb, w2, One );
1320 break;
1321 }
1322 case SWAP2: // w1 w2 w3 w4 -- w3 w4 w1 w2
1323 {
1324 if (echo) bb->setName("SWAP2");
1325 LoadInst* w4 = cast( stack_top( bb ) );
1326 LoadInst* w3 = cast( stack_top( bb, One ) );
1327 LoadInst* w2 = cast( stack_top( bb, Two ) );
1328 LoadInst* w1 = cast( stack_top( bb, Three ) );
1329 replace_top( bb, w2 );
1330 replace_top( bb, w1, One );
1331 replace_top( bb, w4, Two );
1332 replace_top( bb, w3, Three );
1333 break;
1334 }
1335 case OVER: // w1 w2 -- w1 w2 w1
1336 {
1337 if (echo) bb->setName("OVER");
1338 LoadInst* w1 = cast( stack_top( bb, One ) );
1339 push_value( bb, w1 );
1340 break;
1341 }
1342 case OVER2: // w1 w2 w3 w4 -- w1 w2 w3 w4 w1 w2
1343 {
1344 if (echo) bb->setName("OVER2");
1345 LoadInst* w2 = cast( stack_top( bb, Two ) );
1346 LoadInst* w1 = cast( stack_top( bb, Three ) );
1347 incr_stack_index( bb, Two );
1348 replace_top( bb, w2 );
1349 replace_top( bb, w1, One );
1350 break;
1351 }
1352 case ROT: // w1 w2 w3 -- w2 w3 w1
1353 {
1354 if (echo) bb->setName("ROT");
1355 LoadInst* w3 = cast( stack_top( bb ) );
1356 LoadInst* w2 = cast( stack_top( bb, One ) );
1357 LoadInst* w1 = cast( stack_top( bb, Two ) );
1358 replace_top( bb, w1 );
1359 replace_top( bb, w3, One );
1360 replace_top( bb, w2, Two );
1361 break;
1362 }
1363 case ROT2: // w1 w2 w3 w4 w5 w6 -- w3 w4 w5 w6 w1 w2
1364 {
1365 if (echo) bb->setName("ROT2");
1366 LoadInst* w6 = cast( stack_top( bb ) );
1367 LoadInst* w5 = cast( stack_top( bb, One ) );
1368 LoadInst* w4 = cast( stack_top( bb, Two ) );
1369 LoadInst* w3 = cast( stack_top( bb, Three) );
1370 LoadInst* w2 = cast( stack_top( bb, Four ) );
1371 LoadInst* w1 = cast( stack_top( bb, Five ) );
1372 replace_top( bb, w2 );
1373 replace_top( bb, w1, One );
1374 replace_top( bb, w6, Two );
1375 replace_top( bb, w5, Three );
1376 replace_top( bb, w4, Four );
1377 replace_top( bb, w3, Five );
1378 break;
1379 }
1380 case RROT: // w1 w2 w3 -- w3 w1 w2
1381 {
1382 if (echo) bb->setName("RROT2");
1383 LoadInst* w3 = cast( stack_top( bb ) );
1384 LoadInst* w2 = cast( stack_top( bb, One ) );
1385 LoadInst* w1 = cast( stack_top( bb, Two ) );
1386 replace_top( bb, w2 );
1387 replace_top( bb, w1, One );
1388 replace_top( bb, w3, Two );
1389 break;
1390 }
1391 case RROT2: // w1 w2 w3 w4 w5 w6 -- w5 w6 w1 w2 w3 w4
1392 {
1393 if (echo) bb->setName("RROT2");
1394 LoadInst* w6 = cast( stack_top( bb ) );
1395 LoadInst* w5 = cast( stack_top( bb, One ) );
1396 LoadInst* w4 = cast( stack_top( bb, Two ) );
1397 LoadInst* w3 = cast( stack_top( bb, Three) );
1398 LoadInst* w2 = cast( stack_top( bb, Four ) );
1399 LoadInst* w1 = cast( stack_top( bb, Five ) );
1400 replace_top( bb, w4 );
1401 replace_top( bb, w3, One );
1402 replace_top( bb, w2, Two );
1403 replace_top( bb, w1, Three );
1404 replace_top( bb, w6, Four );
1405 replace_top( bb, w5, Five );
1406 break;
1407 }
1408 case TUCK: // w1 w2 -- w2 w1 w2
1409 {
1410 if (echo) bb->setName("TUCK");
1411 LoadInst* w2 = cast( stack_top( bb ) );
1412 LoadInst* w1 = cast( stack_top( bb, One ) );
1413 incr_stack_index( bb );
1414 replace_top( bb, w2 );
1415 replace_top( bb, w1, One );
1416 replace_top( bb, w2, Two );
1417 break;
1418 }
1419 case TUCK2: // w1 w2 w3 w4 -- w3 w4 w1 w2 w3 w4
1420 {
1421 if (echo) bb->setName("TUCK2");
1422 LoadInst* w4 = cast( stack_top( bb ) );
1423 LoadInst* w3 = cast( stack_top( bb, One ) );
1424 LoadInst* w2 = cast( stack_top( bb, Two ) );
1425 LoadInst* w1 = cast( stack_top( bb, Three) );
1426 incr_stack_index( bb, Two );
1427 replace_top( bb, w4 );
1428 replace_top( bb, w3, One );
1429 replace_top( bb, w2, Two );
1430 replace_top( bb, w1, Three );
1431 replace_top( bb, w4, Four );
1432 replace_top( bb, w3, Five );
1433 break;
1434 }
1435 case ROLL: // x0 x1 .. xn n -- x1 .. xn x0
1436 {
1437 /// THIS OEPRATOR IS OMITTED PURPOSEFULLY AND IS LEFT TO THE
1438 /// READER AS AN EXERCISE. THIS IS ONE OF THE MORE COMPLICATED
1439 /// OPERATORS. IF YOU CAN GET THIS ONE RIGHT, YOU COMPLETELY
1440 /// UNDERSTAND HOW BOTH LLVM AND STACKER WOR.
1441 /// HINT: LOOK AT PICK AND SELECT. ROLL IS SIMILAR.
1442 if (echo) bb->setName("ROLL");
1443 break;
1444 }
1445 case PICK: // x0 ... Xn n -- x0 ... Xn x0
1446 {
1447 if (echo) bb->setName("PICK");
1448 LoadInst* n = cast( stack_top( bb ) );
1449 BinaryOperator* addop =
1450 BinaryOperator::create( Instruction::Add, n, One );
1451 bb->getInstList().push_back( addop );
1452 LoadInst* x0 = cast( stack_top( bb, addop ) );
1453 replace_top( bb, x0 );
1454 break;
1455 }
1456 case SELECT: // m n X0..Xm Xm+1 .. Xn -- Xm
1457 {
1458 if (echo) bb->setName("SELECT");
1459 LoadInst* m = cast( stack_top(bb) );
1460 LoadInst* n = cast( stack_top(bb, One) );
1461 BinaryOperator* index =
1462 BinaryOperator::create( Instruction::Add, m, One );
1463 bb->getInstList().push_back( index );
1464 LoadInst* Xm = cast( stack_top(bb, index ) );
1465 BinaryOperator* n_plus_1 =
1466 BinaryOperator::create( Instruction::Add, n, One );
1467 bb->getInstList().push_back( n_plus_1 );
1468 decr_stack_index( bb, n_plus_1 );
1469 replace_top( bb, Xm );
1470 break;
1266 case DROP: // w --
1267 {
1268 if (echo) bb->setName("DROP");
1269 decr_stack_index(bb, One);
1270 break;
1271 }
1272 case DROP2: // w1 w2 --
1273 {
1274 if (echo) bb->setName("DROP2");
1275 decr_stack_index( bb, Two );
1276 break;
1277 }
1278 case NIP: // w1 w2 -- w2
1279 {
1280 if (echo) bb->setName("NIP");
1281 LoadInst* w2 = cast( stack_top( bb ) );
1282 decr_stack_index( bb );
1283 replace_top( bb, w2 );
1284 break;
1285 }
1286 case NIP2: // w1 w2 w3 w4 -- w3 w4
1287 {
1288 if (echo) bb->setName("NIP2");
1289 LoadInst* w4 = cast( stack_top( bb ) );
1290 LoadInst* w3 = cast( stack_top( bb, One ) );
1291 decr_stack_index( bb, Two );
1292 replace_top( bb, w4 );
1293 replace_top( bb, w3, One );
1294 break;
1295 }
1296 case DUP: // w -- w w
1297 {
1298 if (echo) bb->setName("DUP");
1299 LoadInst* w = cast( stack_top( bb ) );
1300 push_value( bb, w );
1301 break;
1302 }
1303 case DUP2: // w1 w2 -- w1 w2 w1 w2
1304 {
1305 if (echo) bb->setName("DUP2");
1306 LoadInst* w2 = cast( stack_top(bb) );
1307 LoadInst* w1 = cast( stack_top(bb, One ) );
1308 incr_stack_index( bb, Two );
1309 replace_top( bb, w1, One );
1310 replace_top( bb, w2 );
1311 break;
1312 }
1313 case SWAP: // w1 w2 -- w2 w1
1314 {
1315 if (echo) bb->setName("SWAP");
1316 LoadInst* w2 = cast( stack_top( bb ) );
1317 LoadInst* w1 = cast( stack_top( bb, One ) );
1318 replace_top( bb, w1 );
1319 replace_top( bb, w2, One );
1320 break;
1321 }
1322 case SWAP2: // w1 w2 w3 w4 -- w3 w4 w1 w2
1323 {
1324 if (echo) bb->setName("SWAP2");
1325 LoadInst* w4 = cast( stack_top( bb ) );
1326 LoadInst* w3 = cast( stack_top( bb, One ) );
1327 LoadInst* w2 = cast( stack_top( bb, Two ) );
1328 LoadInst* w1 = cast( stack_top( bb, Three ) );
1329 replace_top( bb, w2 );
1330 replace_top( bb, w1, One );
1331 replace_top( bb, w4, Two );
1332 replace_top( bb, w3, Three );
1333 break;
1334 }
1335 case OVER: // w1 w2 -- w1 w2 w1
1336 {
1337 if (echo) bb->setName("OVER");
1338 LoadInst* w1 = cast( stack_top( bb, One ) );
1339 push_value( bb, w1 );
1340 break;
1341 }
1342 case OVER2: // w1 w2 w3 w4 -- w1 w2 w3 w4 w1 w2
1343 {
1344 if (echo) bb->setName("OVER2");
1345 LoadInst* w2 = cast( stack_top( bb, Two ) );
1346 LoadInst* w1 = cast( stack_top( bb, Three ) );
1347 incr_stack_index( bb, Two );
1348 replace_top( bb, w2 );
1349 replace_top( bb, w1, One );
1350 break;
1351 }
1352 case ROT: // w1 w2 w3 -- w2 w3 w1
1353 {
1354 if (echo) bb->setName("ROT");
1355 LoadInst* w3 = cast( stack_top( bb ) );
1356 LoadInst* w2 = cast( stack_top( bb, One ) );
1357 LoadInst* w1 = cast( stack_top( bb, Two ) );
1358 replace_top( bb, w1 );
1359 replace_top( bb, w3, One );
1360 replace_top( bb, w2, Two );
1361 break;
1362 }
1363 case ROT2: // w1 w2 w3 w4 w5 w6 -- w3 w4 w5 w6 w1 w2
1364 {
1365 if (echo) bb->setName("ROT2");
1366 LoadInst* w6 = cast( stack_top( bb ) );
1367 LoadInst* w5 = cast( stack_top( bb, One ) );
1368 LoadInst* w4 = cast( stack_top( bb, Two ) );
1369 LoadInst* w3 = cast( stack_top( bb, Three) );
1370 LoadInst* w2 = cast( stack_top( bb, Four ) );
1371 LoadInst* w1 = cast( stack_top( bb, Five ) );
1372 replace_top( bb, w2 );
1373 replace_top( bb, w1, One );
1374 replace_top( bb, w6, Two );
1375 replace_top( bb, w5, Three );
1376 replace_top( bb, w4, Four );
1377 replace_top( bb, w3, Five );
1378 break;
1379 }
1380 case RROT: // w1 w2 w3 -- w3 w1 w2
1381 {
1382 if (echo) bb->setName("RROT2");
1383 LoadInst* w3 = cast( stack_top( bb ) );
1384 LoadInst* w2 = cast( stack_top( bb, One ) );
1385 LoadInst* w1 = cast( stack_top( bb, Two ) );
1386 replace_top( bb, w2 );
1387 replace_top( bb, w1, One );
1388 replace_top( bb, w3, Two );
1389 break;
1390 }
1391 case RROT2: // w1 w2 w3 w4 w5 w6 -- w5 w6 w1 w2 w3 w4
1392 {
1393 if (echo) bb->setName("RROT2");
1394 LoadInst* w6 = cast( stack_top( bb ) );
1395 LoadInst* w5 = cast( stack_top( bb, One ) );
1396 LoadInst* w4 = cast( stack_top( bb, Two ) );
1397 LoadInst* w3 = cast( stack_top( bb, Three) );
1398 LoadInst* w2 = cast( stack_top( bb, Four ) );
1399 LoadInst* w1 = cast( stack_top( bb, Five ) );
1400 replace_top( bb, w4 );
1401 replace_top( bb, w3, One );
1402 replace_top( bb, w2, Two );
1403 replace_top( bb, w1, Three );
1404 replace_top( bb, w6, Four );
1405 replace_top( bb, w5, Five );
1406 break;
1407 }
1408 case TUCK: // w1 w2 -- w2 w1 w2
1409 {
1410 if (echo) bb->setName("TUCK");
1411 LoadInst* w2 = cast( stack_top( bb ) );
1412 LoadInst* w1 = cast( stack_top( bb, One ) );
1413 incr_stack_index( bb );
1414 replace_top( bb, w2 );
1415 replace_top( bb, w1, One );
1416 replace_top( bb, w2, Two );
1417 break;
1418 }
1419 case TUCK2: // w1 w2 w3 w4 -- w3 w4 w1 w2 w3 w4
1420 {
1421 if (echo) bb->setName("TUCK2");
1422 LoadInst* w4 = cast( stack_top( bb ) );
1423 LoadInst* w3 = cast( stack_top( bb, One ) );
1424 LoadInst* w2 = cast( stack_top( bb, Two ) );
1425 LoadInst* w1 = cast( stack_top( bb, Three) );
1426 incr_stack_index( bb, Two );
1427 replace_top( bb, w4 );
1428 replace_top( bb, w3, One );
1429 replace_top( bb, w2, Two );
1430 replace_top( bb, w1, Three );
1431 replace_top( bb, w4, Four );
1432 replace_top( bb, w3, Five );
1433 break;
1434 }
1435 case ROLL: // x0 x1 .. xn n -- x1 .. xn x0
1436 {
1437 /// THIS OEPRATOR IS OMITTED PURPOSEFULLY AND IS LEFT TO THE
1438 /// READER AS AN EXERCISE. THIS IS ONE OF THE MORE COMPLICATED
1439 /// OPERATORS. IF YOU CAN GET THIS ONE RIGHT, YOU COMPLETELY
1440 /// UNDERSTAND HOW BOTH LLVM AND STACKER WOR.
1441 /// HINT: LOOK AT PICK AND SELECT. ROLL IS SIMILAR.
1442 if (echo) bb->setName("ROLL");
1443 break;
1444 }
1445 case PICK: // x0 ... Xn n -- x0 ... Xn x0
1446 {
1447 if (echo) bb->setName("PICK");
1448 LoadInst* n = cast( stack_top( bb ) );
1449 BinaryOperator* addop =
1450 BinaryOperator::create( Instruction::Add, n, One );
1451 bb->getInstList().push_back( addop );
1452 LoadInst* x0 = cast( stack_top( bb, addop ) );
1453 replace_top( bb, x0 );
1454 break;
1455 }
1456 case SELECT: // m n X0..Xm Xm+1 .. Xn -- Xm
1457 {
1458 if (echo) bb->setName("SELECT");
1459 LoadInst* m = cast( stack_top(bb) );
1460 LoadInst* n = cast( stack_top(bb, One) );
1461 BinaryOperator* index =
1462 BinaryOperator::create( Instruction::Add, m, One );
1463 bb->getInstList().push_back( index );
1464 LoadInst* Xm = cast( stack_top(bb, index ) );
1465 BinaryOperator* n_plus_1 =
1466 BinaryOperator::create( Instruction::Add, n, One );
1467 bb->getInstList().push_back( n_plus_1 );
1468 decr_stack_index( bb, n_plus_1 );
1469 replace_top( bb, Xm );
1470 break;
14711471 }
14721472 case MALLOC : // n -- p
14731473 {
1474 if (echo) bb->setName("MALLOC");
1475 // Get the number of bytes to mallocate
1476 LoadInst* op1 = cast( pop_integer(bb) );
1477
1478 // Make sure its a UIntTy
1479 CastInst* caster = new CastInst( op1, Type::UIntTy );
1480 bb->getInstList().push_back( caster );
1481
1482 // Allocate the bytes
1483 MallocInst* mi = new MallocInst( Type::SByteTy, caster );
1484 bb->getInstList().push_back( mi );
1485
1486 // Push the pointer
1487 push_value( bb, mi );
1488 break;
1474 if (echo) bb->setName("MALLOC");
1475 // Get the number of bytes to mallocate
1476 LoadInst* op1 = cast( pop_integer(bb) );
1477
1478 // Make sure its a UIntTy
1479 CastInst* caster = new CastInst( op1, Type::UIntTy );
1480 bb->getInstList().push_back( caster );
1481
1482 // Allocate the bytes
1483 MallocInst* mi = new MallocInst( Type::SByteTy, caster );
1484 bb->getInstList().push_back( mi );
1485
1486 // Push the pointer
1487 push_value( bb, mi );
1488 break;
14891489 }
14901490 case FREE : // p --
14911491 {
1492 if (echo) bb->setName("FREE");
1493 // Pop the value off the stack
1494 CastInst* ptr = cast( pop_string(bb) );
1495
1496 // Free the memory
1497 FreeInst* fi = new FreeInst( ptr );
1498 bb->getInstList().push_back( fi );
1499
1500 break;
1492 if (echo) bb->setName("FREE");
1493 // Pop the value off the stack
1494 CastInst* ptr = cast( pop_string(bb) );
1495
1496 // Free the memory
1497 FreeInst* fi = new FreeInst( ptr );
1498 bb->getInstList().push_back( fi );
1499
1500 break;
15011501 }
15021502 case GET : // p w1 -- p w2
15031503 {
1504 if (echo) bb->setName("GET");
1505 // Get the character index
1506 LoadInst* op1 = cast( stack_top(bb) );
1507 CastInst* chr_idx = new CastInst( op1, Type::LongTy );
1508 bb->getInstList().push_back( chr_idx );
1509
1510 // Get the String pointer
1511 CastInst* ptr = cast( stack_top_string(bb,One) );
1512
1513 // Get address of op1'th element of the string
1514 std::vector indexVec;
1515 indexVec.push_back( chr_idx );
1516 GetElementPtrInst* gep = new GetElementPtrInst( ptr, indexVec );
1517 bb->getInstList().push_back( gep );
1518
1519 // Get the value and push it
1520 LoadInst* loader = new LoadInst( gep );
1521 bb->getInstList().push_back( loader );
1522 CastInst* caster = new CastInst( loader, Type::IntTy );
1523 bb->getInstList().push_back( caster );
1524
1525 // Push the result back on stack
1526 replace_top( bb, caster );
1527
1528 break;
1504 if (echo) bb->setName("GET");
1505 // Get the character index
1506 LoadInst* op1 = cast( stack_top(bb) );
1507 CastInst* chr_idx = new CastInst( op1, Type::LongTy );
1508 bb->getInstList().push_back( chr_idx );
1509
1510 // Get the String pointer
1511 CastInst* ptr = cast( stack_top_string(bb,One) );
1512
1513 // Get address of op1'th element of the string
1514 std::vector indexVec;
1515 indexVec.push_back( chr_idx );
1516 GetElementPtrInst* gep = new GetElementPtrInst( ptr, indexVec );
1517 bb->getInstList().push_back( gep );
1518
1519 // Get the value and push it
1520 LoadInst* loader = new LoadInst( gep );
1521 bb->getInstList().push_back( loader );
1522 CastInst* caster = new CastInst( loader, Type::IntTy );
1523 bb->getInstList().push_back( caster );
1524
1525 // Push the result back on stack
1526 replace_top( bb, caster );
1527
1528 break;
15291529 }
15301530 case PUT : // p w2 w1 -- p
15311531 {
1532 if (echo) bb->setName("PUT");
1533
1534 // Get the value to put
1535 LoadInst* w1 = cast( pop_integer(bb) );
1536
1537 // Get the character index
1538 LoadInst* w2 = cast( pop_integer(bb) );
1539 CastInst* chr_idx = new CastInst( w2, Type::LongTy );
1540 bb->getInstList().push_back( chr_idx );
1541
1542 // Get the String pointer
1543 CastInst* ptr = cast( stack_top_string(bb) );
1544
1545 // Get address of op2'th element of the string
1546 std::vector indexVec;
1547 indexVec.push_back( chr_idx );
1548 GetElementPtrInst* gep = new GetElementPtrInst( ptr, indexVec );
1549 bb->getInstList().push_back( gep );
1550
1551 // Cast the value and put it
1552 CastInst* caster = new CastInst( w1, Type::SByteTy );
1553 bb->getInstList().push_back( caster );
1554 StoreInst* storer = new StoreInst( caster, gep );
1555 bb->getInstList().push_back( storer );
1556
1557 break;
1532 if (echo) bb->setName("PUT");
1533
1534 // Get the value to put
1535 LoadInst* w1 = cast( pop_integer(bb) );
1536
1537 // Get the character index
1538 LoadInst* w2 = cast( pop_integer(bb) );
1539 CastInst* chr_idx = new CastInst( w2, Type::LongTy );
1540 bb->getInstList().push_back( chr_idx );
1541
1542 // Get the String pointer
1543 CastInst* ptr = cast( stack_top_string(bb) );
1544
1545 // Get address of op2'th element of the string
1546 std::vector indexVec;
1547 indexVec.push_back( chr_idx );
1548 GetElementPtrInst* gep = new GetElementPtrInst( ptr, indexVec );
1549 bb->getInstList().push_back( gep );
1550
1551 // Cast the value and put it
1552 CastInst* caster = new CastInst( w1, Type::SByteTy );
1553 bb->getInstList().push_back( caster );
1554 StoreInst* storer = new StoreInst( caster, gep );
1555 bb->getInstList().push_back( storer );
1556
1557 break;
15581558 }
15591559 case RECURSE :
15601560 {
1561 if (echo) bb->setName("RECURSE");
1562 std::vector params;
1563 CallInst* call_inst = new CallInst( TheFunction, params );
1564 bb->getInstList().push_back( call_inst );
1565 break;
1561 if (echo) bb->setName("RECURSE");
1562 std::vector params;
1563 CallInst* call_inst = new CallInst( TheFunction, params );
1564 bb->getInstList().push_back( call_inst );
1565 break;
15661566 }
15671567 case RETURN :
15681568 {
1569 if (echo) bb->setName("RETURN");
1570 bb->getInstList().push_back( new ReturnInst() );
1571 break;
1569 if (echo) bb->setName("RETURN");
1570 bb->getInstList().push_back( new ReturnInst() );
1571 break;
15721572 }
15731573 case EXIT :
15741574 {
1575 if (echo) bb->setName("EXIT");
1576 // Get the result value
1577 LoadInst* op1 = cast(pop_integer(bb));
1578
1579 // Cast down to an integer
1580 CastInst* caster = new CastInst( op1, Type::IntTy );
1581 bb->getInstList().push_back( caster );
1582
1583 // Call exit(3)
1584 std::vector params;
1585 params.push_back(caster);
1586 CallInst* call_inst = new CallInst( TheExit, params );
1587 bb->getInstList().push_back( call_inst );
1588 break;
1575 if (echo) bb->setName("EXIT");
1576 // Get the result value
1577 LoadInst* op1 = cast(pop_integer(bb));
1578
1579 // Cast down to an integer
1580 CastInst* caster = new CastInst( op1, Type::IntTy );
1581 bb->getInstList().push_back( caster );
1582
1583 // Call exit(3)
1584 std::vector params;
1585 params.push_back(caster);
1586 CallInst* call_inst = new CallInst( TheExit, params );
1587 bb->getInstList().push_back( call_inst );
1588 break;
15891589 }
15901590 case TAB :
15911591 {
1592 if (echo) bb->setName("TAB");
1593 // Get the format string for a character
1594 std::vector indexVec;
1595 indexVec.push_back( Zero );
1596 indexVec.push_back( Zero );
1597 GetElementPtrInst* format_gep =
1598 new GetElementPtrInst( ChrFormat, indexVec );
1599 bb->getInstList().push_back( format_gep );
1600
1601 // Get the character to print (a tab)
1602 ConstantSInt* newline = ConstantSInt::get(Type::IntTy,
1603 static_cast('\t'));
1604
1605 // Call printf
1606 std::vector args;
1607 args.push_back( format_gep );
1608 args.push_back( newline );
1609 bb->getInstList().push_back( new CallInst( ThePrintf, args ) );
1610 break;
1592 if (echo) bb->setName("TAB");
1593 // Get the format string for a character
1594 std::vector indexVec;
1595 indexVec.push_back( Zero );
1596 indexVec.push_back( Zero );
1597 GetElementPtrInst* format_gep =
1598 new GetElementPtrInst( ChrFormat, indexVec );
1599 bb->getInstList().push_back( format_gep );
1600
1601 // Get the character to print (a tab)
1602 ConstantSInt* newline = ConstantSInt::get(Type::IntTy,
1603 static_cast('\t'));
1604
1605 // Call printf
1606 std::vector args;
1607 args.push_back( format_gep );
1608 args.push_back( newline );
1609 bb->getInstList().push_back( new CallInst( ThePrintf, args ) );
1610 break;
16111611 }
16121612 case SPACE :
16131613 {
1614 if (echo) bb->setName("SPACE");
1615 // Get the format string for a character
1616 std::vector indexVec;
1617 indexVec.push_back( Zero );
1618 indexVec.push_back( Zero );
1619 GetElementPtrInst* format_gep =
1620 new GetElementPtrInst( ChrFormat, indexVec );
1621 bb->getInstList().push_back( format_gep );
1622
1623 // Get the character to print (a space)
1624 ConstantSInt* newline = ConstantSInt::get(Type::IntTy,
1625 static_cast(' '));
1626
1627 // Call printf
1628 std::vector args;
1629 args.push_back( format_gep );
1630 args.push_back( newline );
1631 bb->getInstList().push_back( new CallInst( ThePrintf, args ) );
1632 break;
1614 if (echo) bb->setName("SPACE");
1615 // Get the format string for a character
1616 std::vector indexVec;
1617 indexVec.push_back( Zero );
1618 indexVec.push_back( Zero );
1619 GetElementPtrInst* format_gep =
1620 new GetElementPtrInst( ChrFormat, indexVec );
1621 bb->getInstList().push_back( format_gep );
1622
1623 // Get the character to print (a space)
1624 ConstantSInt* newline = ConstantSInt::get(Type::IntTy,
1625 static_cast(' '));
1626
1627 // Call printf
1628 std::vector args;
1629 args.push_back( format_gep );
1630 args.push_back( newline );
1631 bb->getInstList().push_back( new CallInst( ThePrintf, args ) );
1632 break;
16331633 }
16341634 case CR :
16351635 {
1636 if (echo) bb->setName("CR");
1637 // Get the format string for a character
1638 std::vector indexVec;
1639 indexVec.push_back( Zero );
1640 indexVec.push_back( Zero );
1641 GetElementPtrInst* format_gep =
1642 new GetElementPtrInst( ChrFormat, indexVec );
1643 bb->getInstList().push_back( format_gep );
1644
1645 // Get the character to print (a newline)
1646 ConstantSInt* newline = ConstantSInt::get(Type::IntTy,
1647 static_cast('\n'));
1648
1649 // Call printf
1650 std::vector args;
1651 args.push_back( format_gep );
1652 args.push_back( newline );
1653 bb->getInstList().push_back( new CallInst( ThePrintf, args ) );
1654 break;
1636 if (echo) bb->setName("CR");
1637 // Get the format string for a character
1638 std::vector indexVec;
1639 indexVec.push_back( Zero );
1640 indexVec.push_back( Zero );
1641 GetElementPtrInst* format_gep =
1642 new GetElementPtrInst( ChrFormat, indexVec );
1643 bb->getInstList().push_back( format_gep );
1644
1645 // Get the character to print (a newline)
1646 ConstantSInt* newline = ConstantSInt::get(Type::IntTy,
1647 static_cast('\n'));
1648
1649 // Call printf
1650 std::vector args;
1651 args.push_back( format_gep );
1652 args.push_back( newline );
1653 bb->getInstList().push_back( new CallInst( ThePrintf, args ) );
1654 break;
16551655 }
16561656 case IN_STR :
16571657 {
1658 if (echo) bb->setName("IN_STR");
1659 // Make room for the value result
1660 incr_stack_index(bb);
1661 GetElementPtrInst* gep_value =
1662 cast(get_stack_pointer(bb));
1663 CastInst* caster =
1664 new CastInst( gep_value, PointerType::get( Type::SByteTy ) );
1665
1666 // Make room for the count result
1667 incr_stack_index(bb);
1668 GetElementPtrInst* gep_count =
1669 cast(get_stack_pointer(bb));
1670
1671 // Call scanf(3)
1672 std::vector args;
1673 args.push_back( InStrFormat );
1674 args.push_back( caster );
1675 CallInst* scanf = new CallInst( TheScanf, args );
1676 bb->getInstList().push_back( scanf );
1677
1678 // Store the result
1679 bb->getInstList().push_back( new StoreInst( scanf, gep_count ) );
1680 break;
1658 if (echo) bb->setName("IN_STR");
1659 // Make room for the value result
1660 incr_stack_index(bb);
1661 GetElementPtrInst* gep_value =
1662 cast(get_stack_pointer(bb));
1663 CastInst* caster =
1664 new CastInst( gep_value, PointerType::get( Type::SByteTy ) );
1665
1666 // Make room for the count result
1667 incr_stack_index(bb);
1668 GetElementPtrInst* gep_count =
1669 cast(get_stack_pointer(bb));
1670
1671 // Call scanf(3)
1672 std::vector args;
1673 args.push_back( InStrFormat );
1674 args.push_back( caster );
1675 CallInst* scanf = new CallInst( TheScanf, args );
1676 bb->getInstList().push_back( scanf );
1677
1678 // Store the result
1679 bb->getInstList().push_back( new StoreInst( scanf, gep_count ) );
1680 break;
16811681 }
16821682 case IN_NUM :
16831683 {
1684 if (echo) bb->setName("IN_NUM");
1685 // Make room for the value result
1686 incr_stack_index(bb);
1687 GetElementPtrInst* gep_value =
1688 cast(get_stack_pointer(bb));
1689
1690 // Make room for the count result
1691 incr_stack_index(bb);
1692 GetElementPtrInst* gep_count =
1693 cast(get_stack_pointer(bb));
1694
1695 // Call scanf(3)
1696 std::vector args;
1697 args.push_back( InStrFormat );
1698 args.push_back( gep_value );
1699 CallInst* scanf = new CallInst( TheScanf, args );
1700 bb->getInstList().push_back( scanf );
1701
1702 // Store the result
1703 bb->getInstList().push_back( new StoreInst( scanf, gep_count ) );
1704 break;
1684 if (echo) bb->setName("IN_NUM");
1685 // Make room for the value result
1686 incr_stack_index(bb);
1687 GetElementPtrInst* gep_value =
1688 cast(get_stack_pointer(bb));
1689
1690 // Make room for the count result
1691 incr_stack_index(bb);
1692 GetElementPtrInst* gep_count =
1693 cast(get_stack_pointer(bb));
1694
1695 // Call scanf(3)
1696 std::vector args;
1697 args.push_back( InStrFormat );
1698 args.push_back( gep_value );
1699 CallInst* scanf = new CallInst( TheScanf, args );
1700 bb->getInstList().push_back( scanf );
1701
1702 // Store the result
1703 bb->getInstList().push_back( new StoreInst( scanf, gep_count ) );
1704 break;
17051705 }
17061706 case IN_CHAR :
17071707 {
1708 if (echo) bb->setName("IN_CHAR");
1709 // Make room for the value result
1710 incr_stack_index(bb);
1711 GetElementPtrInst* gep_value =
1712 cast(get_stack_pointer(bb));
1713
1714 // Make room for the count result
1715 incr_stack_index(bb);
1716 GetElementPtrInst* gep_count =
1717 cast(get_stack_pointer(bb));
1718
1719 // Call scanf(3)
1720 std::vector args;
1721 args.push_back( InChrFormat );
1722 args.push_back( gep_value );
1723 CallInst* scanf = new CallInst( TheScanf, args );
1724 bb->getInstList().push_back( scanf );
1725
1726 // Store the result
1727 bb->getInstList().push_back( new StoreInst( scanf, gep_count ) );
1728 break;
1708 if (echo) bb->setName("IN_CHAR");
1709 // Make room for the value result
1710 incr_stack_index(bb);
1711 GetElementPtrInst* gep_value =
1712 cast(get_stack_pointer(bb));
1713
1714 // Make room for the count result
1715 incr_stack_index(bb);
1716 GetElementPtrInst* gep_count =
1717 cast(get_stack_pointer(bb));
1718
1719 // Call scanf(3)
1720 std::vector args;
1721 args.push_back( InChrFormat );
1722 args.push_back( gep_value );
1723 CallInst* scanf = new CallInst( TheScanf, args );
1724 bb->getInstList().push_back( scanf );
1725
1726 // Store the result
1727 bb->getInstList().push_back( new StoreInst( scanf, gep_count ) );
1728 break;
17291729 }
17301730 case OUT_STR :
17311731 {
1732 if (echo) bb->setName("OUT_STR");
1733 LoadInst* op1 = cast(stack_top(bb));
1734
1735 // Get the address of the format string
1736 std::vector indexVec;
1737 indexVec.push_back( Zero );
1738 indexVec.push_back( Zero );
1739 GetElementPtrInst* format_gep =
1740 new GetElementPtrInst( StrFormat, indexVec );
1741 bb->getInstList().push_back( format_gep );
1742 // Build function call arguments
1743 std::vector args;
1744 args.push_back( format_gep );
1745 args.push_back( op1 );
1746 // Call printf
1747 bb->getInstList().push_back( new CallInst( ThePrintf, args ) );
1748 break;
1732 if (echo) bb->setName("OUT_STR");
1733 LoadInst* op1 = cast(stack_top(bb));
1734
1735 // Get the address of the format string
1736 std::vector indexVec;
1737 indexVec.push_back( Zero );
1738 indexVec.push_back( Zero );
1739 GetElementPtrInst* format_gep =
1740 new GetElementPtrInst( StrFormat, indexVec );
1741 bb->getInstList().push_back( format_gep );
1742 // Build function call arguments
1743 std::vector args;
1744 args.push_back( format_gep );
1745 args.push_back( op1 );
1746 // Call printf
1747 bb->getInstList().push_back( new CallInst( ThePrintf, args ) );
1748 break;
17491749 }
17501750 case OUT_NUM :
17511751 {
1752 if (echo) bb->setName("OUT_NUM");
1753 // Pop the numeric operand off the stack
1754 LoadInst* op1 = cast(stack_top(bb));
1755
1756 // Get the address of the format string
1757 std::vector indexVec;
1758 indexVec.push_back( Zero );
1759 indexVec.push_back( Zero );
1760 GetElementPtrInst* format_gep =
1761 new GetElementPtrInst( NumFormat, indexVec );
1762 bb->getInstList().push_back( format_gep );
1763
1764 // Build function call arguments
1765 std::vector args;
1766 args.push_back( format_gep );
1767 args.push_back( op1 );
1768
1769 // Call printf
1770 bb->getInstList().push_back( new CallInst( ThePrintf, args ) );
1771 break;
1752 if (echo) bb->setName("OUT_NUM");
1753 // Pop the numeric operand off the stack
1754 LoadInst* op1 = cast(stack_top(bb));
1755
1756 // Get the address of the format string
1757 std::vector indexVec;
1758 indexVec.push_back( Zero );
1759 indexVec.push_back( Zero );
1760 GetElementPtrInst* format_gep =
1761 new GetElementPtrInst( NumFormat, indexVec );
1762 bb->getInstList().push_back( format_gep );
1763
1764 // Build function call arguments
1765 std::vector args;
1766 args.push_back( format_gep );
1767 args.push_back( op1 );
1768
1769 // Call printf
1770 bb->getInstList().push_back( new CallInst( ThePrintf, args ) );
1771 break;
17721772 }
17731773 case OUT_CHAR :
17741774 {
1775 if (echo) bb->setName("OUT_CHAR");
1776 // Pop the character operand off the stack
1777 LoadInst* op1 = cast(stack_top(bb));
1778
1779 // Get the address of the format string
1780 std::vector indexVec;
1781 indexVec.push_back( Zero );
1782 indexVec.push_back( Zero );
1783 GetElementPtrInst* format_gep =
1784 new GetElementPtrInst( ChrFormat, indexVec );
1785 bb->getInstList().push_back( format_gep );
1786
1787 // Build function call arguments
1788 std::vector args;
1789 args.push_back( format_gep );
1790 args.push_back( op1 );
1791 // Call printf
1792 bb->getInstList().push_back( new CallInst( ThePrintf, args ) );
1793 break;
1775 if (echo) bb->setName("OUT_CHAR");
1776 // Pop the character operand off the stack
1777 LoadInst* op1 = cast(stack_top(bb));
1778
1779 // Get the address of the format string
1780 std::vector indexVec;
1781 indexVec.push_back( Zero );
1782 indexVec.push_back( Zero );
1783 GetElementPtrInst* format_gep =
1784 new GetElementPtrInst( ChrFormat, indexVec );
1785 bb->getInstList().push_back( format_gep );
1786
1787 // Build function call arguments
1788 std::vector args;
1789 args.push_back( format_gep );
1790 args.push_back( op1 );
1791 // Call printf
1792 bb->getInstList().push_back( new CallInst( ThePrintf, args ) );
1793 break;
17941794 }
17951795 default :
17961796 {
1797 ThrowException(std::string("Compiler Error: Unhandled token #"));
1797 ThrowException(std::string("Compiler Error: Unhandled token #"));
17981798 }
17991799 }
18001800
4545 /// @name Constructors and Operators
4646 /// @{
4747 public:
48 /// Default Constructor
49 StackerCompiler();
50
51 /// Destructor
52 ~StackerCompiler();
53 private:
54 /// Do not copy StackerCompilers
55 StackerCompiler(const StackerCompiler&);
56
57 /// Do not copy StackerCompilers.
58 StackerCompiler& operator=(const StackerCompiler& );
48 /// Default Constructor
49 StackerCompiler();
50
51 /// Destructor
52 ~StackerCompiler();
53 private:
54 /// Do not copy StackerCompilers
55 StackerCompiler(const StackerCompiler&);
56
57 /// Do not copy StackerCompilers.
58 StackerCompiler& operator=(const StackerCompiler& );
5959
6060 /// @}
6161 /// @name High Level Interface
6262 /// @{
6363 public:
64 /// @brief Compile a single file to LLVM bytecode.
65 ///
66 /// To use the StackerCompiler, just create one on
67 /// the stack and call this method.
68 Module* compile(
69 const std::string& filename, ///< File to compile
70 bool echo, ///< Causes compiler to echo output
64 /// @brief Compile a single file to LLVM bytecode.
65 ///
66 /// To use the StackerCompiler, just create one on
67 /// the stack and call this method.
68 Module* compile(
69 const std::string& filename, ///< File to compile
70 bool echo, ///< Causes compiler to echo output
7171 unsigned optLevel, ///< Level of optimization
72 size_t stack_size ); ///< Size of generated stack
72 size_t stack_size ); ///< Size of generated stack
7373 /// @}
7474 /// @name Accessors
7575 /// @{
7676 public:
77 /// @brief Returns the name of the file being compiled.
78 std::string& filename() { return CurFilename; }
77 /// @brief Returns the name of the file being compiled.
78 std::string& filename() { return CurFilename; }
7979
8080 /// @}
8181 /// @name Parse Handling Methods
8282 /// @{
8383 private:
84 /// Allow only the parser to access these methods. No
85 /// one else should call them.
86 friend int Stackerparse();
87
88 /// @brief Handle the start of a module
89 Module* handle_module_start();
90
91 /// @brief Handle the end of a module
92 /// @param mod The module we're defining.
93 Module* handle_module_end( Module* mod );
94
95 /// @brief Handle the start of a list of definitions
96 Module* handle_definition_list_start( );
97
98 /// @brief Handle the end of a list of definitions
99 /// @param mod The module we're constructing
100 /// @param definition A definition (function) to add to the module
101 Module* handle_definition_list_end( Module* mod, Function* definition );
102
103 /// @brief Handle creation of the MAIN definition
104 /// @param func The function to be used as the MAIN definition
105 Function* handle_main_definition( Function* func );
106
107 /// @brief Handle a forward definition
108 /// @param name The name of the definition being declared
109 Function* handle_forward( char* name );
110
111 /// @brief Handle a general definition
112 /// @param name The name of the definition being defined
113 /// @param func The Function definition.
114 Function* handle_definition( char* name, Function* func );
115
116 /// @brief Handle the start of a definition's word list
117 Function* handle_word_list_start();
118
119 /// @brief Handle the end of a definition's word list
120 /// @param func The function to which the basic block is added
121 /// @param next The block to add to the function
122 Function* handle_word_list_end( Function* func, BasicBlock* next );
123
124 /// @brief Handle an if statement, possibly without an else
125 /// @brief ifTrue The block to execute if true
126 /// @brief ifFalse The optional block to execute if false
127 BasicBlock* handle_if( char* ifTrue, char* ifFalse = 0 );
128
129 /// @brief Handle a while statement
130 /// @brief todo The block to repeatedly execute
131 BasicBlock* handle_while( char* todo );
132
133 /// @brief Handle an identifier to call the identified definition
134 /// @param name The name of the identifier to be called.
135 BasicBlock* handle_identifier( char * name );
136
137 /// @brief Handle the push of a string onto the stack
138 /// @param value The string to be pushed.
139 BasicBlock* handle_string( char * value );
140
141 /// @brief Handle the push of an integer onto the stack.
142 /// @param value The integer value to be pushed.
143 BasicBlock* handle_integer( const int64_t value );
144
145 /// @brief Handle one of the reserved words (given as a token)
146 BasicBlock* handle_word( int tkn );
84 /// Allow only the parser to access these methods. No
85 /// one else should call them.
86 friend int Stackerparse();
87
88 /// @brief Handle the start of a module
89 Module* handle_module_start();
90
91 /// @brief Handle the end of a module
92 /// @param mod The module we're defining.
93 Module* handle_module_end( Module* mod );
94
95 /// @brief Handle the start of a list of definitions
96 Module* handle_definition_list_start( );
97
98 /// @brief Handle the end of a list of definitions
99 /// @param mod The module we're constructing
100 /// @param definition A definition (function) to add to the module
101 Module* handle_definition_list_end( Module* mod, Function* definition );
102
103 /// @brief Handle creation of the MAIN definition
104 /// @param func The function to be used as the MAIN definition
105 Function* handle_main_definition( Function* func );
106
107 /// @brief Handle a forward definition
108 /// @param name The name of the definition being declared
109 Function* handle_forward( char* name );
110
111 /// @brief Handle a general definition
112 /// @param name The name of the definition being defined
113 /// @param func The Function definition.
114 Function* handle_definition( char* name, Function* func );
115
116 /// @brief Handle the start of a definition's word list
117 Function* handle_word_list_start();
118
119 /// @brief Handle the end of a definition's word list
120 /// @param func The function to which the basic block is added
121 /// @param next The block to add to the function
122 Function* handle_word_list_end( Function* func, BasicBlock* next );
123
124 /// @brief Handle an if statement, possibly without an else
125 /// @brief ifTrue The block to execute if true
126 /// @brief ifFalse The optional block to execute if false
127 BasicBlock* handle_if( char* ifTrue, char* ifFalse = 0 );
128
129 /// @brief Handle a while statement
130 /// @brief todo The block to repeatedly execute
131 BasicBlock* handle_while( char* todo );
132
133 /// @brief Handle an identifier to call the identified definition
134 /// @param name The name of the identifier to be called.
135 BasicBlock* handle_identifier( char * name );
136
137 /// @brief Handle the push of a string onto the stack
138 /// @param value The string to be pushed.
139 BasicBlock* handle_string( char * value );
140
141 /// @brief Handle the push of an integer onto the stack.
142 /// @param value The integer value to be pushed.
143 BasicBlock* handle_integer( const int64_t value );
144
145 /// @brief Handle one of the reserved words (given as a token)
146 BasicBlock* handle_word( int tkn );
147147
148148 /// @}
149149 /// @name Utility functions
150150 /// @{
151151 public:
152 /// @brief Throws an exception to indicate an error
153 /// @param message The message to be output
154 /// @param line Override for the current line no
155 static inline void ThrowException( const std::string &message,
156 int line = -1)
157 {
158 if (line == -1) line = Stackerlineno;
159 // TODO: column number in exception
160 throw ParseException(TheInstance->CurFilename, message, line);
161 }
162 private:
163 /// @brief Generate code to increment the stack index
164 Instruction* incr_stack_index( BasicBlock* bb, Value* );
165 /// @brief Generate code to decrement the stack index.
166 Instruction* decr_stack_index( BasicBlock* bb, Value* );
167 /// @brief Generate code to dereference the top of stack.
168 Instruction* get_stack_pointer( BasicBlock* bb, Value* );
169 /// @brief Generate code to push any value onto the stack.
170 Instruction* push_value( BasicBlock* bb, Value* value );
171 /// @brief Generate code to push a constant integer onto the stack.
172 Instruction* push_integer( BasicBlock* bb, int64_t value );
173 /// @brief Generate code to pop an integer off the stack.
174 Instruction* pop_integer( BasicBlock* bb );
175 /// @brief Generate code to push a string pointer onto the stack.
176 Instruction* push_string( BasicBlock* bb, const char* value );
177 /// @brief Generate code to pop a string pointer off the stack.
178 Instruction* pop_string( BasicBlock* bb );
179 /// @brief Generate code to get the top stack element.
180 Instruction* stack_top( BasicBlock* bb, Value* index );
181 /// @brief Generate code to get the top stack element as a string.
182 Instruction* stack_top_string( BasicBlock* bb, Value* index );
183 /// @brief Generate code to replace the top element of the stack.
184 Instruction* replace_top( BasicBlock* bb, Value* new_top, Value* index);
152 /// @brief Throws an exception to indicate an error
153 /// @param message The message to be output
154 /// @param line Override for the current line no
155 static inline void ThrowException( const std::string &message,
156 int line = -1)
157 {
158 if (line == -1) line = Stackerlineno;
159 // TODO: column number in exception
160 throw ParseException(TheInstance->CurFilename, message, line);
161 }
162 private:
163 /// @brief Generate code to increment the stack index
164 Instruction* incr_stack_index( BasicBlock* bb, Value* );
165 /// @brief Generate code to decrement the stack index.
166 Instruction* decr_stack_index( BasicBlock* bb, Value* );
167 /// @brief Generate code to dereference the top of stack.
168 Instruction* get_stack_pointer( BasicBlock* bb, Value* );
169 /// @brief Generate code to push any value onto the stack.
170 Instruction* push_value( BasicBlock* bb, Value* value );
171 /// @brief Generate code to push a constant integer onto the stack.
172 Instruction* push_integer( BasicBlock* bb, int64_t value );
173 /// @brief Generate code to pop an integer off the stack.
174 Instruction* pop_integer( BasicBlock* bb );
175 /// @brief Generate code to push a string pointer onto the stack.
176 Instruction* push_string( BasicBlock* bb, const char* value );
177 /// @brief Generate code to pop a string pointer off the stack.
178 Instruction* pop_string( BasicBlock* bb );
179 /// @brief Generate code to get the top stack element.
180 Instruction* stack_top( BasicBlock* bb, Value* index );
181 /// @brief Generate code to get the top stack element as a string.
182 Instruction* stack_top_string( BasicBlock* bb, Value* index );
183 /// @brief Generate code to replace the top element of the stack.
184 Instruction* replace_top( BasicBlock* bb, Value* new_top, Value* index);
185185
186186 /// @}
187187 /// @name Data Members (used during parsing)
188188 /// @{
189189 public:
190 static StackerCompiler* TheInstance; ///< The instance for the parser
191
192 private:
193 std::string CurFilename; ///< Current file name
194 Module* TheModule; ///< Module instance we'll build
195 Function* TheFunction; ///< Function we're building
196 FunctionType* DefinitionType; ///< FT for Definitions
197 GlobalVariable* TheStack; ///< For referencing _stack_
198 GlobalVariable* TheIndex; ///< For referencing _index_
199 Function* TheScanf; ///< External input function
200 Function* ThePrintf; ///< External output function
201 Function* TheExit; ///< External exit function
202 GlobalVariable* StrFormat; ///< Format for strings
203 GlobalVariable* NumFormat; ///< Format for numbers
204 GlobalVariable* ChrFormat; ///< Format for chars
205 GlobalVariable* InStrFormat; ///< Format for input strings
206 GlobalVariable* InNumFormat; ///< Format for input numbers
207 GlobalVariable* InChrFormat; ///< Format for input chars
208 ConstantInt* Zero; ///< long constant 0
209 ConstantInt* One; ///< long constant 1
210 ConstantInt* Two; ///< long constant 2
211 ConstantInt* Three; ///< long constant 3
212 ConstantInt* Four; ///< long constant 4
213 ConstantInt* Five; ///< long constant 5
214 std::vector no_arguments; ///< no arguments for Stacker
215 bool echo; ///< Echo flag
216 size_t stack_size; ///< Size of stack to gen.
217 ArrayType* stack_type; ///< The type of the stack
190 static StackerCompiler* TheInstance; ///< The instance for the parser
191
192 private:
193 std::string CurFilename; ///< Current file name
194 Module* TheModule; ///< Module instance we'll build
195 Function* TheFunction; ///< Function we're building
196 FunctionType* DefinitionType; ///< FT for Definitions
197 GlobalVariable* TheStack; ///< For referencing _stack_
198 GlobalVariable* TheIndex; ///< For referencing _index_
199 Function* TheScanf; ///< External input function
200 Function* ThePrintf; ///< External output function
201 Function* TheExit; ///< External exit function
202 GlobalVariable* StrFormat; ///< Format for strings
203 GlobalVariable* NumFormat; ///< Format for numbers
204 GlobalVariable* ChrFormat; ///< Format for chars
205 GlobalVariable* InStrFormat; ///< Format for input strings
206 GlobalVariable* InNumFormat; ///< Format for input numbers
207 GlobalVariable* InChrFormat; ///< Format for input chars
208 ConstantInt* Zero; ///< long constant 0
209 ConstantInt* One; ///< long constant 1
210 ConstantInt* Two; ///< long constant 2
211 ConstantInt* Three; ///< long constant 3
212 ConstantInt* Four; ///< long constant 4
213 ConstantInt* Five; ///< long constant 5
214 std::vector no_arguments; ///< no arguments for Stacker
215 bool echo; ///< Echo flag
216 size_t stack_size; ///< Size of stack to gen.
217 ArrayType* stack_type; ///< The type of the stack
218218 /// @}
219219 };
220220
0 //===-- stacker_rt.c - Runtime Support For Stacker Compiler -----*- C++ -*-===//
1 //
1 //
22 // The LLVM Compiler Infrastructure
33 //
4 // This file was developed by Reid Spencer and donated to the LLVM research
5 // group and is distributed under the University of Illinois Open Source
4 // This file was developed by Reid Spencer and donated to the LLVM research
5 // group and is distributed under the University of Illinois Open Source
66 // License. See LICENSE.TXT for details.
7 //
7 //
88 //===----------------------------------------------------------------------===//
99 //
1010 // This file defines a stack dumping function that can be used for debugging.
3232 printf("Stack Dump:\n");
3333 for (i = _index_; i > 0; i-- )
3434 {
35 printf("#%03lld: %lld\n", (long long int) i, (long long int) _stack_[i] );
35 printf("#%03lld: %lld\n", (long long int) i, (long long int) _stack_[i] );
3636 }
3737 }
3838
4949 // so that they get popped in the order presented
5050 while ( a > 0 )
5151 {
52 if ( isdigit( (int) argv[--a][0] ) )
53 {
54 _stack_[_index_++] = atoll( argv[a] );
55 }
56 else
57 {
58 _stack_[_index_++] = (int64_t) (intptr_t) argv[a];
59 }
52 if ( isdigit( (int) argv[--a][0] ) )
53 {
54 _stack_[_index_++] = atoll( argv[a] );
55 }
56 else
57 {
58 _stack_[_index_++] = (int64_t) (intptr_t) argv[a];
59 }
6060 }
6161
6262 // Put the argument count on the stack
6767
6868 // Return last item on the stack
6969 if ( _index_ >= 0 )
70 return _stack_[_index_];
70 return _stack_[_index_];
7171 return -1;
7272 }
3333
3434 static cl::opt
3535 OutputFilename("o", cl::desc("Override output filename"),
36 cl::value_desc("filename"));
36 cl::value_desc("filename"));
3737
3838 static cl::opt
3939 Force("f", cl::desc("Overwrite output files"));
4040
4141 static cl::opt
4242 StackSize("s", cl::desc("Specify program maximum stack size"),
43 cl::init(1024), cl::value_desc("stack size"));
43 cl::init(1024), cl::value_desc("stack size"));
4444
4545 static cl::opt
4646 DumpAsm("d", cl::desc("Print LLVM Assembly as parsed"), cl::Hidden);
0 /*
11 * File: sample.h
22 *
3 * This is a sample header file that is global to the entire project.
4 * It is located here so that everyone will find it.
3 * This is a sample header file that is global to the entire project.
4 * It is located here so that everyone will find it.
55 */
66 extern int compute_sample (int a);
77
11 * File: sample.c
22 *
33 * Description:
4 * This is a sample source file for a library. It helps to demonstrate
5 * how to setup a project that uses the LLVM build system, header files,
6 * and libraries.
4 * This is a sample source file for a library. It helps to demonstrate
5 * how to setup a project that uses the LLVM build system, header files,
6 * and libraries.
77 */
88
99 #include
1818 int
1919 compute_sample (int a)
2020 {
21 return a;
21 return a;
2222 }
2323
77 int
88 main (int argc, char ** argv)
99 {
10 printf ("%d\n", compute_sample (5));
11 exit (0);
10 printf ("%d\n", compute_sample (5));
11 exit (0);
1212 }
1313
11
22 struct duration {
33 duration operator/=(int c) {
4 return *this;
4 return *this;
55 }
66 };
77
88 void a000090() {
9 duration() /= 1;
9 duration() /= 1;
1010 }
44 // was mistakenly "thinking" that 'foo' took a structure by component.
55
66 struct C {
7 int A, B;
8 ~C() {}
7 int A, B;
8 ~C() {}
99 };
1010
1111 void foo(C b);
1212
1313 void test(C *P) {
14 foo(*P);
14 foo(*P);
1515 }
1616
0 // RUN: %llvmgcc -S %s -o - | llvm-as -f -o /dev/null
11
2 /* This testcase causes a symbol table collision. Type names and variable
2 /* This testcase causes a symbol table collision. Type names and variable
33 * names should be in distinct namespaces
44 */
55
66 typedef struct foo {
7 int X, Y;
7 int X, Y;
88 } FOO;
99
1010 static FOO foo[100];
1111
1212 int test() {
13 return foo[4].Y;
13 return foo[4].Y;
1414 }
1515
22 /* GCC wasn't handling 64 bit constants right fixed */
33
44 void main() {
5 long long Var = 123455678902ll;
6 printf("%lld\n", Var);
7
5 long long Var = 123455678902ll;
6 printf("%lld\n", Var);
87 }
22 #include
33
44 int test(char *X) {
5 /* LLVM-GCC used to emit:
6 %.LC0 = internal global [3 x sbyte] c"\1F\FFFFFF8B\00"
7 */
8 return strcmp(X, "\037\213");
5 /* LLVM-GCC used to emit:
6 %.LC0 = internal global [3 x sbyte] c"\1F\FFFFFF8B\00"
7 */
8 return strcmp(X, "\037\213");
99 }
0 // RUN: %llvmgcc -S %s -o - | llvm-as -f -o /dev/null
11
2 /* GCC was not escaping quotes in string constants correctly, so this would
2 /* GCC was not escaping quotes in string constants correctly, so this would
33 * get emitted:
44 * %.LC1 = internal global [32 x sbyte] c"*** Word "%s" on line %d is not\00"
55 */
66
77 const char *Foo() {
8 return "*** Word \"%s\" on line %d is not";
8 return "*** Word \"%s\" on line %d is not";
99 }
99 }
1010
1111 void *test() {
12 foo(12);
13 return &Y;
12 foo(12);
13 return &Y;
1414 }
44 #include
55
66 int main(int argc, char **argv) {
7 char *C = (char*)alloca(argc);
8 strcpy(C, argv[0]);
9 puts(C);
7 char *C = (char*)alloca(argc);
8 strcpy(C, argv[0]);
9 puts(C);
1010 }
22 #include
33
44 void test() {
5 fprintf(stderr, "testing\n");
5 fprintf(stderr, "testing\n");
66 }
2222 struct SubStruct *SSP;
2323 char c;
2424 int y;
25 };
25 };
2626
2727 struct Quad GlobalQuad = { 4, {1, 2}, 0, 3, 156 };
2828
6464
6565
6666 int BadFunc(float Val) {
67 int Result;
67 int Result;
6868 if (Val > 12.345) Result = 4;
6969 return Result; /* Test use of undefined value */
7070 }
7979 int Result = Param;
8080
8181 {{{{
82 char c; int X;
83 EF1(&Result, &c, &X);
84 }}}
85
86 { // c & X are duplicate names!
87 char c; int X;
88 EF1(&Result, &c, &X);
89 }
82 char c; int X;
83 EF1(&Result, &c, &X);
84 }}}
85
86 { // c & X are duplicate names!
87 char c; int X;
88 EF1(&Result, &c, &X);
89 }
9090
9191 }
9292 return Result;
128128 for (i = 0; i < 100; ++i)
129129 A[i] = i*4;
130130
131 return A[A[0]]; //SumArray(A, 100);
131 return A[A[0]]; //SumArray(A, 100);
132132 }
133133
134134
140140
141141 ExternFunc(-1, 0, (short)argc, 2);
142142 //func(argc, argc);
143
143
144144 for (i = 0; i < 10; i++)
145145 puts(argv[3]);
146146 return 0;
158158
159159
160160 void strcpy(char *s1, char *s2) {
161 while (*s1++ = *s2++);
161 while (*s1++ = *s2++);
162162 }
163163
164164 void strcat(char *s1, char *s2) {
165 while (*s1++);
166 s1--;
167 while (*s1++ = *s2++);
165 while (*s1++);
166 s1--;
167 while (*s1++ = *s2++);
168168 }
169169
170170 int strcmp(char *s1, char *s2) {
171 while (*s1++ == *s2++);
172 if (*s1 == 0) {
173 if (*s2 == 0) {
174 return 0;
175 } else {
176 return -1;
177 }
171 while (*s1++ == *s2++);
172 if (*s1 == 0) {
173 if (*s2 == 0) {
174 return 0;
178175 } else {
179 if (*s2 == 0) {
180 return 1;
181 } else {
182 return (*(--s1) - *(--s2));
183 }
176 return -1;
184177 }
178 } else {
179 if (*s2 == 0) {
180 return 1;
181 } else {
182 return (*(--s1) - *(--s2));
183 }
184 }
185185 }
186186
55 };
66
77 union X foo() {
8 union X A;
9 A.B = (void*)123;
10 return A;
8 union X A;
9 A.B = (void*)123;
10 return A;
1111 }
66 union X {
77 char C;
88 int A, Z;
9 long long B;
9 long long B;
1010 void *b1;
1111 struct { int A; long long Z; } Q;
1212 };
1313
1414 union X foo(union X A) {
15 A.C = 123;
16 A.A = 39249;
17 //A.B = (void*)123040123321;
18 A.B = 12301230123123LL;
19 A.Z = 1;
20 return A;
15 A.C = 123;
16 A.A = 39249;
17 //A.B = (void*)123040123321;
18 A.B = 12301230123123LL;
19 A.Z = 1;
20 return A;
2121 }
22 int tcount;
33 void test(char *, const char*, int);
44 void foo() {
5 char Buf[10];
6 test(Buf, "n%%%d", tcount++);
5 char Buf[10];
6 test(Buf, "n%%%d", tcount++);
77 }
77 union X { char X; void *B; int a, b, c, d;};
88
99 union X foo() {
10 union X Global;
11 Global.B = (void*)123; /* Interesting part */
12 return Global;
10 union X Global;
11 Global.B = (void*)123; /* Interesting part */
12 return Global;
1313 }
1414
1515 void main() {
16 union X test = foo();
17 printf("0x%p", test.B);
16 union X test = foo();
17 printf("0x%p", test.B);
1818 }
11
22
33 int foo(int *A, unsigned X) {
4 return A[X];
4 return A[X];
55 }
33 void foo() {}
44
55 void bar() {
6 foo(1, 2, 3); /* Too many arguments passed */
6 foo(1, 2, 3); /* Too many arguments passed */
77 }
None // This file can be used to see what a native C compiler is generating for a
0 // This file can be used to see what a native C compiler is generating for a
11 // variety of interesting operations.
22 //
33 // RUN: %llvmgcc -c %s -o - | llc
2222 _Bool setgt(int X, int Y) {
2323 return X > Y;
2424 }
25
25
11 static int q;
22
33 void foo() {
4 int t = q;
5 q = t + 1;
4 int t = q;
5 q = t + 1;
66 }
77 int main() {
8 q = 0;
9 foo();
10 q = q - 1;
8 q = 0;
9 foo();
10 q = q - 1;
1111
12 return q;
12 return q;
1313 }
1414
1515 // This is the source that corresponds to funccall.ll