summaryrefslogtreecommitdiff
path: root/src/main/java/com/seaofnodes/simple/codegen/LinkMem.java
blob: 252b5bf0e91b120702ca0160ed309bc559d6d8d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.seaofnodes.simple.codegen;

import com.seaofnodes.simple.node.Node;
import com.seaofnodes.simple.type.TypeStruct;
import com.seaofnodes.simple.util.SB;
import com.seaofnodes.simple.util.Utils;

// In-memory linking
public class LinkMem {
    final CodeGen _code;
    LinkMem( CodeGen code ) { _code = code; }

    public CodeGen link(Encoding enc) {
        // Patch external calls internally
        enc.patchGlobalRelocations();

        // Place constant pool after code, static data after constants
        int code  = 0;                     // Code start
        int cpool = (enc._bits .size() + code  + 15) & -16;  // pad to 16
        int sdata = (enc._cpool.size() + cpool + 15) & -16;


        // Patch local ops, e.g. loading float constants from the constant pool
        for( Node op : enc._bigCons.keySet() ) {
            Encoding.Relo relo = enc._bigCons.get(op);
            int target = enc._data.address(enc._data.object(relo._t),cpool,sdata);
            ((RIPRelSize)relo._op).patch(enc, relo._opStart, enc.opLen(relo._op), target - relo._opStart);
        }

        enc._data.link(cpool,sdata);
        return _code;
    }
}