1d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller/*
2d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller * Copyright 2011 Christoph Bumiller
3d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller *
4d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller * Permission is hereby granted, free of charge, to any person obtaining a
5d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller * copy of this software and associated documentation files (the "Software"),
6d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller * to deal in the Software without restriction, including without limitation
7d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller * and/or sell copies of the Software, and to permit persons to whom the
9d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller * Software is furnished to do so, subject to the following conditions:
10d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller *
11d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller * The above copyright notice and this permission notice shall be included in
12d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller * all copies or substantial portions of the Software.
13d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller *
14d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller * SOFTWARE.
21d2d19ea51fa3575a8d014a69a9b835c335728817Christoph Bumiller */
2257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
2357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller#include "nv50/codegen/nv50_ir.h"
2457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller#include "nv50/codegen/nv50_ir_target.h"
2557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
2657594065c30feec9376be9b2132659f7d87362eeChristoph Bumillernamespace nv50_ir {
2757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
2857594065c30feec9376be9b2132659f7d87362eeChristoph Bumillerconst uint8_t Target::operationSrcNr[OP_LAST + 1] =
2957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller{
3057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   0, 0,                   // NOP, PHI
3157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   0, 0, 0, 0,             // UNION, SPLIT, MERGE, CONSTRAINT
3257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   1, 1, 2,                // MOV, LOAD, STORE
3357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   2, 2, 2, 2, 2, 3, 3, 3, // ADD, SUB, MUL, DIV, MOD, MAD, FMA, SAD
3457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   1, 1, 1,                // ABS, NEG, NOT
3557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   2, 2, 2, 2, 2,          // AND, OR, XOR, SHL, SHR
3657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   2, 2, 1,                // MAX, MIN, SAT
3757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   1, 1, 1, 1,             // CEIL, FLOOR, TRUNC, CVT
3857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   3, 3, 3, 2, 3, 3,       // SET_AND,OR,XOR, SET, SELP, SLCT
3957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   1, 1, 1, 1, 1, 1,       // RCP, RSQ, LG2, SIN, COS, EX2
4057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   1, 1, 1, 1, 1, 2,       // EXP, LOG, PRESIN, PREEX2, SQRT, POW
4157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   0, 0, 0, 0, 0,          // BRA, CALL, RET, CONT, BREAK,
4257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   0, 0, 0,                // PRERET,CONT,BREAK
4357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   0, 0, 0, 0, 0, 0,       // BRKPT, JOINAT, JOIN, DISCARD, EXIT, MEMBAR
4457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   1, 1, 2, 1, 2,          // VFETCH, PFETCH, EXPORT, LINTERP, PINTERP
4557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   1, 1,                   // EMIT, RESTART
4657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   1, 1, 1,                // TEX, TXB, TXL,
4757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   1, 1, 1, 1, 1,          // TXF, TXQ, TXD, TXG, TEXCSAA
4857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   1, 2,                   // SULD, SUST
4957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   1, 1,                   // DFDX, DFDY
5057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   1, 2, 2, 2, 0, 0,       // RDSV, WRSV, PIXLD, QUADOP, QUADON, QUADPOP
51e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   2, 3, 2, 0,             // POPCNT, INSBF, EXTBF, TEXBAR
5257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   0
5357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller};
5457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
55afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumillerconst OpClass Target::operationClass[OP_LAST + 1] =
56afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller{
57afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // NOP; PHI; UNION, SPLIT, MERGE, CONSTRAINT
58afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_OTHER,
59afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_PSEUDO,
60afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_PSEUDO, OPCLASS_PSEUDO, OPCLASS_PSEUDO, OPCLASS_PSEUDO,
61afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // MOV; LOAD; STORE
62afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_MOVE,
63afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_LOAD,
64afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_STORE,
65afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // ADD, SUB, MUL; DIV, MOD; MAD, FMA, SAD
66afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_ARITH, OPCLASS_ARITH, OPCLASS_ARITH,
67afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_ARITH, OPCLASS_ARITH,
68afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_ARITH, OPCLASS_ARITH, OPCLASS_ARITH,
69afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // ABS, NEG; NOT, AND, OR, XOR; SHL, SHR
70afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_CONVERT, OPCLASS_CONVERT,
71afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_LOGIC, OPCLASS_LOGIC, OPCLASS_LOGIC, OPCLASS_LOGIC,
72afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_SHIFT, OPCLASS_SHIFT,
73afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // MAX, MIN
74afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_COMPARE, OPCLASS_COMPARE,
75afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // SAT, CEIL, FLOOR, TRUNC; CVT
76afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_CONVERT, OPCLASS_CONVERT, OPCLASS_CONVERT, OPCLASS_CONVERT,
77afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_CONVERT,
78afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // SET(AND,OR,XOR); SELP, SLCT
79afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_COMPARE, OPCLASS_COMPARE, OPCLASS_COMPARE, OPCLASS_COMPARE,
80afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_COMPARE, OPCLASS_COMPARE,
81afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // RCP, RSQ, LG2, SIN, COS; EX2, EXP, LOG, PRESIN, PREEX2; SQRT, POW
82afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_SFU, OPCLASS_SFU, OPCLASS_SFU, OPCLASS_SFU, OPCLASS_SFU,
83afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_SFU, OPCLASS_SFU, OPCLASS_SFU, OPCLASS_SFU, OPCLASS_SFU,
84afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_SFU, OPCLASS_SFU,
85afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // BRA, CALL, RET; CONT, BREAK, PRE(RET,CONT,BREAK); BRKPT, JOINAT, JOIN
86afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_FLOW, OPCLASS_FLOW, OPCLASS_FLOW,
87afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_FLOW, OPCLASS_FLOW, OPCLASS_FLOW, OPCLASS_FLOW, OPCLASS_FLOW,
88afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_FLOW, OPCLASS_FLOW, OPCLASS_FLOW,
89afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // DISCARD, EXIT
90afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_FLOW, OPCLASS_FLOW,
91afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // MEMBAR
92afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_OTHER,
93afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // VFETCH, PFETCH, EXPORT
94afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_LOAD, OPCLASS_OTHER, OPCLASS_STORE,
95afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // LINTERP, PINTERP
96afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_SFU, OPCLASS_SFU,
97afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // EMIT, RESTART
98afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_OTHER, OPCLASS_OTHER,
99afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // TEX, TXB, TXL, TXF; TXQ, TXD, TXG, TEXCSAA
100afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_TEXTURE, OPCLASS_TEXTURE, OPCLASS_TEXTURE, OPCLASS_TEXTURE,
101afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_TEXTURE, OPCLASS_TEXTURE, OPCLASS_TEXTURE, OPCLASS_TEXTURE,
102afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // SULD, SUST
103afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_SURFACE, OPCLASS_SURFACE,
104afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // DFDX, DFDY, RDSV, WRSV; PIXLD, QUADOP, QUADON, QUADPOP
105afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_OTHER, OPCLASS_OTHER, OPCLASS_OTHER, OPCLASS_OTHER,
106afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_OTHER, OPCLASS_OTHER, OPCLASS_OTHER, OPCLASS_OTHER,
107afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // POPCNT, INSBF, EXTBF
108afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_OTHER, OPCLASS_OTHER, OPCLASS_OTHER,
109afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   // TEXBAR
110afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_OTHER,
111afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   OPCLASS_PSEUDO // LAST
112afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller};
113afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller
11457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
11557594065c30feec9376be9b2132659f7d87362eeChristoph Bumillerextern Target *getTargetNVC0(unsigned int chipset);
116322bc7ed68ed92233c97168c036d0aa50c11a20eChristoph Bumillerextern Target *getTargetNV50(unsigned int chipset);
11757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
11857594065c30feec9376be9b2132659f7d87362eeChristoph BumillerTarget *Target::create(unsigned int chipset)
11957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller{
12057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   switch (chipset & 0xf0) {
12157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   case 0xc0:
1224517153278b078b031bb4af10a4d69050eaec9d6Ben Skeggs   case 0xd0:
123e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   case 0xe0:
12457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      return getTargetNVC0(chipset);
12557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   case 0x50:
12657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   case 0x80:
12757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   case 0x90:
12857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   case 0xa0:
129322bc7ed68ed92233c97168c036d0aa50c11a20eChristoph Bumiller      return getTargetNV50(chipset);
13057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   default:
13157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      ERROR("unsupported target: NV%x\n", chipset);
13257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      return 0;
13357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   }
13457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller}
13557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
13657594065c30feec9376be9b2132659f7d87362eeChristoph Bumillervoid Target::destroy(Target *targ)
13757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller{
13857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   delete targ;
13957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller}
14057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
141322bc7ed68ed92233c97168c036d0aa50c11a20eChristoph BumillerCodeEmitter::CodeEmitter(const Target *target) : targ(target)
142322bc7ed68ed92233c97168c036d0aa50c11a20eChristoph Bumiller{
143322bc7ed68ed92233c97168c036d0aa50c11a20eChristoph Bumiller}
144322bc7ed68ed92233c97168c036d0aa50c11a20eChristoph Bumiller
14557594065c30feec9376be9b2132659f7d87362eeChristoph Bumillervoid
14657594065c30feec9376be9b2132659f7d87362eeChristoph BumillerCodeEmitter::setCodeLocation(void *ptr, uint32_t size)
14757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller{
14857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   code = reinterpret_cast<uint32_t *>(ptr);
14957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   codeSize = 0;
15057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   codeSizeLimit = size;
15157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller}
15257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
15357594065c30feec9376be9b2132659f7d87362eeChristoph Bumillervoid
15457594065c30feec9376be9b2132659f7d87362eeChristoph BumillerCodeEmitter::printBinary() const
15557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller{
15657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   uint32_t *bin = code - codeSize / 4;
15757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   INFO("program binary (%u bytes)", codeSize);
15857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   for (unsigned int pos = 0; pos < codeSize / 4; ++pos) {
15957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      if ((pos % 8) == 0)
16057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         INFO("\n");
16157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      INFO("%08x ", bin[pos]);
16257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   }
16357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   INFO("\n");
16457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller}
16557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
166afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumillerstatic inline uint32_t sizeToBundlesNVE4(uint32_t size)
167afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller{
168afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller   return (size + 55) / 56;
169afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller}
170afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller
17157594065c30feec9376be9b2132659f7d87362eeChristoph Bumillervoid
17257594065c30feec9376be9b2132659f7d87362eeChristoph BumillerCodeEmitter::prepareEmission(Program *prog)
17357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller{
17457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   for (ArrayList::Iterator fi = prog->allFuncs.iterator();
17557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller        !fi.end(); fi.next()) {
17657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      Function *func = reinterpret_cast<Function *>(fi.get());
17757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      func->binPos = prog->binSize;
17857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      prepareEmission(func);
179afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller
180afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller      // adjust sizes & positions for schedulding info:
181afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller      if (prog->getTarget()->hasSWSched) {
182afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller         BasicBlock *bb = NULL;
183afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller         for (int i = 0; i < func->bbCount; ++i) {
184afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller            bb = func->bbArray[i];
185afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller            const uint32_t oldPos = bb->binPos;
186afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller            const uint32_t oldEnd = bb->binPos + bb->binSize;
187afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller            uint32_t adjPos = oldPos + sizeToBundlesNVE4(oldPos) * 8;
188afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller            uint32_t adjEnd = oldEnd + sizeToBundlesNVE4(oldEnd) * 8;
189afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller            bb->binPos = adjPos;
190afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller            bb->binSize = adjEnd - adjPos;
191afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller         }
192afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller         if (bb)
193afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller            func->binSize = bb->binPos + bb->binSize;
194afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller      }
195afcd7b5d1614a8a758ccb4353a9c31a601c9b9b4Christoph Bumiller
19657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      prog->binSize += func->binSize;
19757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   }
19857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller}
19957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
20057594065c30feec9376be9b2132659f7d87362eeChristoph Bumillervoid
20157594065c30feec9376be9b2132659f7d87362eeChristoph BumillerCodeEmitter::prepareEmission(Function *func)
20257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller{
20357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   func->bbCount = 0;
20457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   func->bbArray = new BasicBlock * [func->cfg.getSize()];
20557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
20657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   BasicBlock::get(func->cfg.getRoot())->binPos = func->binPos;
20757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
20878de8c8ab54c50c96bc3fae2fe0976054e0acd14Francisco Jerez   for (IteratorRef it = func->cfg.iteratorCFG(); !it->end(); it->next())
20978de8c8ab54c50c96bc3fae2fe0976054e0acd14Francisco Jerez      prepareEmission(BasicBlock::get(*it));
21057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller}
21157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
21257594065c30feec9376be9b2132659f7d87362eeChristoph Bumillervoid
21357594065c30feec9376be9b2132659f7d87362eeChristoph BumillerCodeEmitter::prepareEmission(BasicBlock *bb)
21457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller{
21557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   Instruction *i, *next;
21657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   Function *func = bb->getFunction();
21757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   int j;
21857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   unsigned int nShort;
21957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
22057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   for (j = func->bbCount - 1; j >= 0 && !func->bbArray[j]->binSize; --j);
22157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
22257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   for (; j >= 0; --j) {
22357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      BasicBlock *in = func->bbArray[j];
22457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      Instruction *exit = in->getExit();
22557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
22657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      if (exit && exit->op == OP_BRA && exit->asFlow()->target.bb == bb) {
22757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         in->binSize -= 8;
22857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         func->binSize -= 8;
22957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
23057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         for (++j; j < func->bbCount; ++j)
23157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller            func->bbArray[j]->binPos -= 8;
23257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
23357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         in->remove(exit);
23457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      }
23557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      bb->binPos = in->binPos + in->binSize;
23657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      if (in->binSize) // no more no-op branches to bb
23757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         break;
23857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   }
23957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   func->bbArray[func->bbCount++] = bb;
24057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
24157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   if (!bb->getExit())
24257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      return;
24357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
24457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   // determine encoding size, try to group short instructions
24557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   nShort = 0;
24657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   for (i = bb->getEntry(); i; i = next) {
24757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      next = i->next;
24857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
24957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      i->encSize = getMinEncodingSize(i);
25057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      if (next && i->encSize < 8)
25157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         ++nShort;
25257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      else
25357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      if ((nShort & 1) && next && getMinEncodingSize(next) == 4) {
25457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         if (i->isCommutationLegal(i->next)) {
25557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller            bb->permuteAdjacent(i, next);
25657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller            next->encSize = 4;
25757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller            next = i;
25857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller            i = i->prev;
25957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller            ++nShort;
26057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         } else
26157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         if (i->isCommutationLegal(i->prev) && next->next) {
26257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller            bb->permuteAdjacent(i->prev, i);
26357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller            next->encSize = 4;
26457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller            next = next->next;
26557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller            bb->binSize += 4;
26657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller            ++nShort;
26757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         } else {
26857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller            i->encSize = 8;
26957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller            i->prev->encSize = 8;
27057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller            bb->binSize += 4;
27157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller            nShort = 0;
27257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         }
27357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      } else {
27457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         i->encSize = 8;
27557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         if (nShort & 1) {
27657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller            i->prev->encSize = 8;
27757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller            bb->binSize += 4;
27857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         }
27957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         nShort = 0;
28057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      }
28157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      bb->binSize += i->encSize;
28257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   }
28357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
28457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   if (bb->getExit()->encSize == 4) {
28557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      assert(nShort);
28657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      bb->getExit()->encSize = 8;
28757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      bb->binSize += 4;
28857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
28957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      if ((bb->getExit()->prev->encSize == 4) && !(nShort & 1)) {
29057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         bb->binSize += 8;
29157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         bb->getExit()->prev->encSize = 8;
29257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      }
29357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   }
29457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   assert(!bb->getEntry() || (bb->getExit() && bb->getExit()->encSize == 8));
29557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
29657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   func->binSize += bb->binSize;
29757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller}
29857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
29998116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerezvoid
30098116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco JerezProgram::emitSymbolTable(struct nv50_ir_prog_info *info)
30198116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez{
30298116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez   unsigned int n = 0, nMax = allFuncs.getSize();
30398116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez
30498116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez   info->bin.syms =
30598116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez      (struct nv50_ir_prog_symbol *)MALLOC(nMax * sizeof(*info->bin.syms));
30698116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez
30798116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez   for (ArrayList::Iterator fi = allFuncs.iterator();
30898116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez        !fi.end();
30998116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez        fi.next(), ++n) {
31098116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez      Function *f = (Function *)fi.get();
31198116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez      assert(n < nMax);
31298116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez
31398116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez      info->bin.syms[n].label = f->getLabel();
31498116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez      info->bin.syms[n].offset = f->binPos;
31598116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez   }
31698116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez
31798116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez   info->bin.numSyms = n;
31898116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez}
31998116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez
32057594065c30feec9376be9b2132659f7d87362eeChristoph Bumillerbool
32157594065c30feec9376be9b2132659f7d87362eeChristoph BumillerProgram::emitBinary(struct nv50_ir_prog_info *info)
32257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller{
32357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   CodeEmitter *emit = target->getCodeEmitter(progType);
32457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
32557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   emit->prepareEmission(this);
32657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
32757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   if (dbgFlags & NV50_IR_DEBUG_BASIC)
32857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      this->print();
32957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
33057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   if (!binSize) {
33157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      code = NULL;
33257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      return false;
33357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   }
33457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   code = reinterpret_cast<uint32_t *>(MALLOC(binSize));
33557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   if (!code)
33657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      return false;
33757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   emit->setCodeLocation(code, binSize);
33857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
33957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   for (ArrayList::Iterator fi = allFuncs.iterator(); !fi.end(); fi.next()) {
34057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      Function *fn = reinterpret_cast<Function *>(fi.get());
34157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
34257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      assert(emit->getCodeSize() == fn->binPos);
34357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
34457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      for (int b = 0; b < fn->bbCount; ++b)
34557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         for (Instruction *i = fn->bbArray[b]->getEntry(); i; i = i->next)
34657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller            emit->emitInstruction(i);
34757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   }
34857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   info->bin.relocData = emit->getRelocInfo();
34957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
35098116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez   emitSymbolTable(info);
35198116cc3dc3fc2cd84990cc2c968f05fe2978b4aFrancisco Jerez
352322bc7ed68ed92233c97168c036d0aa50c11a20eChristoph Bumiller   // the nvc0 driver will print the binary iself together with the header
353322bc7ed68ed92233c97168c036d0aa50c11a20eChristoph Bumiller   if ((dbgFlags & NV50_IR_DEBUG_BASIC) && getTarget()->getChipset() < 0xc0)
354322bc7ed68ed92233c97168c036d0aa50c11a20eChristoph Bumiller      emit->printBinary();
355322bc7ed68ed92233c97168c036d0aa50c11a20eChristoph Bumiller
35657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   delete emit;
35757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   return true;
35857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller}
35957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
36057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller#define RELOC_ALLOC_INCREMENT 8
36157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
36257594065c30feec9376be9b2132659f7d87362eeChristoph Bumillerbool
36357594065c30feec9376be9b2132659f7d87362eeChristoph BumillerCodeEmitter::addReloc(RelocEntry::Type ty, int w, uint32_t data, uint32_t m,
36457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller                      int s)
36557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller{
36657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   unsigned int n = relocInfo ? relocInfo->count : 0;
36757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
36857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   if (!(n % RELOC_ALLOC_INCREMENT)) {
36957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      size_t size = sizeof(RelocInfo) + n * sizeof(RelocEntry);
37057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      relocInfo = reinterpret_cast<RelocInfo *>(
37157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         REALLOC(relocInfo, n ? size : 0,
37257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller                 size + RELOC_ALLOC_INCREMENT * sizeof(RelocEntry)));
37357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      if (!relocInfo)
37457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller         return false;
375974102c7c27e45b0fb661e9374b2c51c9108922aChristoph Bumiller      if (n == 0)
376974102c7c27e45b0fb661e9374b2c51c9108922aChristoph Bumiller         memset(relocInfo, 0, sizeof(RelocInfo));
37757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   }
37857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   ++relocInfo->count;
37957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
38057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   relocInfo->entry[n].data = data;
38157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   relocInfo->entry[n].mask = m;
38257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   relocInfo->entry[n].offset = codeSize + w * 4;
38357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   relocInfo->entry[n].bitPos = s;
38457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   relocInfo->entry[n].type = ty;
38557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
38657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   return true;
38757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller}
38857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
38957594065c30feec9376be9b2132659f7d87362eeChristoph Bumillervoid
39057594065c30feec9376be9b2132659f7d87362eeChristoph BumillerRelocEntry::apply(uint32_t *binary, const RelocInfo *info) const
39157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller{
39257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   uint32_t value = 0;
39357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
39457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   switch (type) {
39557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   case TYPE_CODE: value = info->codePos; break;
39657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   case TYPE_BUILTIN: value = info->libPos; break;
39757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   case TYPE_DATA: value = info->dataPos; break;
39857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   default:
39957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      assert(0);
40057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      break;
40157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   }
40257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   value += data;
40357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   value = (bitPos < 0) ? (value >> -bitPos) : (value << bitPos);
40457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
40557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   binary[offset / 4] &= ~mask;
40657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   binary[offset / 4] |= value & mask;
40757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller}
40857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
40957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller} // namespace nv50_ir
41057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
41157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
41257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller#include "nv50/codegen/nv50_ir_driver.h"
41357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
41457594065c30feec9376be9b2132659f7d87362eeChristoph Bumillerextern "C" {
41557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
41657594065c30feec9376be9b2132659f7d87362eeChristoph Bumillervoid
41757594065c30feec9376be9b2132659f7d87362eeChristoph Bumillernv50_ir_relocate_code(void *relocData, uint32_t *code,
41857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller                      uint32_t codePos,
41957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller                      uint32_t libPos,
42057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller                      uint32_t dataPos)
42157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller{
42257594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   nv50_ir::RelocInfo *info = reinterpret_cast<nv50_ir::RelocInfo *>(relocData);
42357594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
42457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   info->codePos = codePos;
42557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   info->libPos = libPos;
42657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   info->dataPos = dataPos;
42757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
42857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   for (unsigned int i = 0; i < info->count; ++i)
42957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller      info->entry[i].apply(code, info);
43057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller}
43157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
43257594065c30feec9376be9b2132659f7d87362eeChristoph Bumillervoid
43357594065c30feec9376be9b2132659f7d87362eeChristoph Bumillernv50_ir_get_target_library(uint32_t chipset,
43457594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller                           const uint32_t **code, uint32_t *size)
43557594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller{
43657594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   nv50_ir::Target *targ = nv50_ir::Target::create(chipset);
43757594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   targ->getBuiltinCode(code, size);
43857594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller   nv50_ir::Target::destroy(targ);
43957594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller}
44057594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller
44157594065c30feec9376be9b2132659f7d87362eeChristoph Bumiller}
442