1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "Nucleus.hpp" 16 #include "Routine.hpp" 17 18 namespace sw 19 { 20 #define For(init, cond, inc) \ 21 init; \ 22 for(llvm::BasicBlock *loopBB__ = beginLoop(), \ 23 *bodyBB__ = Nucleus::createBasicBlock(), \ 24 *endBB__ = Nucleus::createBasicBlock(), \ 25 *onceBB__ = endBB__; \ 26 onceBB__ && branch(cond, bodyBB__, endBB__); \ 27 inc, onceBB__ = 0, Nucleus::createBr(loopBB__), Nucleus::setInsertBlock(endBB__)) 28 29 #define While(cond) For(((void*)0), cond, ((void*)0)) 30 31 #define Do \ 32 { \ 33 llvm::BasicBlock *body = Nucleus::createBasicBlock(); \ 34 Nucleus::createBr(body); \ 35 Nucleus::setInsertBlock(body); 36 37 #define Until(cond) \ 38 llvm::BasicBlock *end = Nucleus::createBasicBlock(); \ 39 Nucleus::createCondBr((cond).value, end, body); \ 40 Nucleus::setInsertBlock(end); \ 41 } 42 43 #define If(cond) \ 44 for(llvm::BasicBlock *trueBB__ = Nucleus::createBasicBlock(), \ 45 *falseBB__ = Nucleus::createBasicBlock(), \ 46 *endBB__ = Nucleus::createBasicBlock(), \ 47 *onceBB__ = endBB__; \ 48 onceBB__ && branch(cond, trueBB__, falseBB__); \ 49 onceBB__ = 0, Nucleus::createBr(endBB__), Nucleus::setInsertBlock(falseBB__), Nucleus::createBr(endBB__), Nucleus::setInsertBlock(endBB__)) 50 51 #define Else \ 52 for(llvm::BasicBlock *endBB__ = Nucleus::getInsertBlock(), \ 53 *falseBB__ = Nucleus::getPredecessor(endBB__), \ 54 *onceBB__ = endBB__; \ 55 onceBB__ && elseBlock(falseBB__); \ 56 onceBB__ = 0, Nucleus::createBr(endBB__), Nucleus::setInsertBlock(endBB__)) 57 }