compiler.cpp revision 741463e18d8235025de649210e7f88a1b6e7af5a
1// 2// Copyright 2012 Francisco Jerez 3// 4// Permission is hereby granted, free of charge, to any person obtaining a 5// copy of this software and associated documentation files (the "Software"), 6// to deal in the Software without restriction, including without limitation 7// the rights to use, copy, modify, merge, publish, distribute, sublicense, 8// and/or sell copies of the Software, and to permit persons to whom the 9// Software is furnished to do so, subject to the following conditions: 10// 11// The above copyright notice and this permission notice shall be included in 12// all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17// THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20// SOFTWARE. 21// 22 23#include <sstream> 24 25#include "core/compiler.hpp" 26 27#include "tgsi/tgsi_parse.h" 28#include "tgsi/tgsi_text.h" 29#include "util/u_memory.h" 30 31using namespace clover; 32 33namespace { 34 void 35 read_header(const std::string &header, module &m) { 36 std::istringstream ls(header); 37 std::string line; 38 39 while (getline(ls, line)) { 40 std::istringstream ts(line); 41 std::string name, tok; 42 module::size_t offset; 43 compat::vector<module::argument> args; 44 45 if (!(ts >> name)) 46 continue; 47 48 if (!(ts >> offset)) 49 throw build_error("invalid kernel start address"); 50 51 while (ts >> tok) { 52 if (tok == "scalar") 53 args.push_back({ module::argument::scalar, 4 }); 54 else if (tok == "global") 55 args.push_back({ module::argument::global, 4 }); 56 else if (tok == "local") 57 args.push_back({ module::argument::local, 4 }); 58 else if (tok == "constant") 59 args.push_back({ module::argument::constant, 4 }); 60 else if (tok == "image2d_rd") 61 args.push_back({ module::argument::image2d_rd, 4 }); 62 else if (tok == "image2d_wr") 63 args.push_back({ module::argument::image2d_wr, 4 }); 64 else if (tok == "image3d_rd") 65 args.push_back({ module::argument::image3d_rd, 4 }); 66 else if (tok == "image3d_wr") 67 args.push_back({ module::argument::image3d_wr, 4 }); 68 else if (tok == "sampler") 69 args.push_back({ module::argument::sampler, 0 }); 70 else 71 throw build_error("invalid kernel argument"); 72 } 73 74 m.syms.push_back({ name, 0, offset, args }); 75 } 76 } 77 78 void 79 read_body(const char *source, module &m) { 80 tgsi_token prog[1024]; 81 82 if (!tgsi_text_translate(source, prog, Elements(prog))) 83 throw build_error("translate failed"); 84 85 unsigned sz = tgsi_num_tokens(prog) * sizeof(tgsi_token); 86 m.secs.push_back({ 0, module::section::text, sz, { (char *)prog, sz } }); 87 } 88} 89 90module 91clover::compile_program_tgsi(const compat::string &source) { 92 const char *body = source.find("COMP\n"); 93 module m; 94 95 read_header({ source.begin(), body }, m); 96 read_body(body, m); 97 98 return m; 99} 100