summaryrefslogtreecommitdiff
path: root/chapter21/src
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2025-04-04 12:29:46 -0700
committerCliff Click <cliffc@acm.org>2025-04-04 12:29:46 -0700
commit887f3d9caf68b051c630bab6c8895778be8f044f (patch)
treebe4280afdd66025a95e645f6dacb861450a42f47 /chapter21/src
parentcc32b0cf801620f1d289cb6ae183e079111540fc (diff)
downloadSimple-887f3d9caf68b051c630bab6c8895778be8f044f.tar.gz
Simple-887f3d9caf68b051c630bab6c8895778be8f044f.zip
Partial progress cpool in ELF
Align functions to 16b
Diffstat (limited to 'chapter21/src')
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/codegen/ElfFile.java30
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java100
2 files changed, 64 insertions, 66 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/codegen/ElfFile.java b/chapter21/src/main/java/com/seaofnodes/simple/codegen/ElfFile.java
index 5db0bb75..32fd99a8 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/codegen/ElfFile.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/codegen/ElfFile.java
@@ -213,26 +213,18 @@ public class ElfFile {
/* creates function and stores where it starts*/
private final HashMap<TypeFunPtr,Symbol> _funcs = new HashMap<>();
private void encodeFunctions(SymbolSection symbols, DataSection text) {
- int func_start = 0;
for( int i=0; i<_code._cfg._len; i++ ) {
- Node bb = _code._cfg.at(i);
- if( bb instanceof FunNode f ) {
- // skip until the function ends
- while( !(_code._cfg.at(i) instanceof ReturnNode) )
- i++;
-
- Node r = _code._cfg.at(i);
- int end = _code._encoding._opStart[r._nid] + _code._encoding._opLen[r._nid];
-
- Symbol func = new Symbol(f._name, text._index, SYM_BIND_GLOBAL, SYM_TYPE_FUNC);
- func._size = end - func_start;
- func._value = func_start;
- symbols.push(func);
- _funcs.put(f.sig(), func);
-
- // next function starts where the last one ends
- func_start = end;
- }
+ if( !(_code._cfg.at(i) instanceof FunNode fun) ) continue;
+ // skip until the function ends
+ while( !(_code._cfg.at(i) instanceof ReturnNode ret) )
+ i++;
+ int end = _code._encoding._opStart[ret._nid] + _code._encoding._opLen[ret._nid];
+
+ Symbol func = new Symbol(fun._name, text._index, SYM_BIND_GLOBAL, SYM_TYPE_FUNC);
+ func._value = _code._encoding._opStart[fun._nid];
+ func._size = end - func._value;
+ symbols.push(func);
+ _funcs.put(fun.sig(), func);
}
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java b/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
index 8c894f8a..845e7bb3 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
@@ -88,8 +88,8 @@ public class Encoding {
buf[idx+3] = (byte)(val>>24);
}
- void pad8() {
- while( (_bits.size()+7 & -8) > _bits.size() )
+ void pad(int n) {
+ while( (_bits.size()+n-1 & -n) > _bits.size() )
_bits.write(0);
}
@@ -120,9 +120,7 @@ public class Encoding {
// Store t as a 32/64 bit constant in the code space; generate RIP-relative
// addressing to load it
-
public final HashMap<Node,Type> _bigCons = new HashMap<>();
- public final HashMap<Node,Integer> _cpool = new HashMap<>();
public void largeConstant( Node relo, Type t ) {
assert t.isConstant();
_bigCons.put(relo,t);
@@ -139,14 +137,14 @@ public class Encoding {
// Record opcode start and length.
writeEncodings();
- // Write any large constants into a constant pool; they
- // are accessed by RIP-relative addressing.
- writeConstantPool();
-
// Short-form RIP-relative support: replace long encodings with short
// encodings and compact the code, changing all the offsets.
compactShortForm();
+ // Write any large constants into a constant pool; they
+ // are accessed by RIP-relative addressing.
+ writeConstantPool(true);
+
// Patch RIP-relative and local encodings now.
patchLocalRelocations();
}
@@ -271,6 +269,7 @@ public class Encoding {
if( !(bb instanceof MachNode mach0) )
_opStart[bb._nid] = _bits.size();
else if( bb instanceof FunNode fun ) {
+ pad(16);
_fun = fun; // Currently encoding function
_opStart[bb._nid] = _bits.size();
mach0.encoding( this );
@@ -284,44 +283,7 @@ public class Encoding {
}
}
}
- pad8();
- }
-
- // Write the constant pool
- private void writeConstantPool() {
- // TODO: Check for cpool dups
- HashSet<Type> ts = new HashSet<>();
- for( Type t : _bigCons.values() ) {
- if( ts.contains(t) )
- throw Utils.TODO(); // Dup! Compress!
- ts.add(t);
- }
-
- // Write the 8-byte constants
- for( Node relo : _bigCons.keySet() ) {
- Type t = _bigCons.get(relo);
- if( t.log_size()==3 ) {
- // Map from relo to constant start
- _cpool.put(relo,_bits.size());
- long x = t instanceof TypeInteger ti
- ? ti.value()
- : Double.doubleToRawLongBits(((TypeFloat)t).value());
- add8(x);
- }
- }
-
- // Write the 4-byte constants
- for( Node relo : _bigCons.keySet() ) {
- Type t = _bigCons.get(relo);
- if( t.log_size()==2 ) {
- // Map from relo to constant start
- _cpool.put(relo,_bits.size());
- int x = t instanceof TypeInteger ti
- ? (int)ti.value()
- : Float.floatToRawIntBits((float)((TypeFloat)t).value());
- add4(x);
- }
- }
+ pad(16);
}
// Short-form RIP-relative support: replace short encodings with long
@@ -367,7 +329,7 @@ public class Encoding {
// larger size... which will shrink the padding and allow the
// short form to work. Too bad.
if( !_cpool.isEmpty() )
- pad8();
+ pad(8);
}
@@ -388,6 +350,50 @@ public class Encoding {
}
}
+ // Write the constant pool; either into the code space
+ // and patch locally, or into another BAOS for emission
+ // to the ELF file.
+ public final HashMap<Node,Integer> _cpool = new HashMap<>();
+ public final BAOS _cbits = new BAOS();
+ private void writeConstantPool(boolean elf) {
+ HashSet<Type> ts = new HashSet<>();
+ for( Type t : _bigCons.values() ) {
+ if( ts.contains(t) )
+ throw Utils.TODO(); // Dup! Compress!
+ ts.add(t);
+ }
+
+ // Write the 8-byte constants
+ for( Node relo : _bigCons.keySet() ) {
+ Type t = _bigCons.get(relo);
+ if( t.log_size()==3 ) {
+ long x = t instanceof TypeInteger ti
+ ? ti.value()
+ : Double.doubleToRawLongBits(((TypeFloat)t).value());
+ // Map from relo to constant start
+ //if( elf ) _cbits.write8(x);
+ //else {
+ // Else local patch
+ _cpool.put(relo,_bits.size());
+ add8(x);
+ //}
+ }
+ }
+
+ // Write the 4-byte constants
+ for( Node relo : _bigCons.keySet() ) {
+ Type t = _bigCons.get(relo);
+ if( t.log_size()==2 ) {
+ // Map from relo to constant start
+ _cpool.put(relo,_bits.size());
+ int x = t instanceof TypeInteger ti
+ ? (int)ti.value()
+ : Float.floatToRawIntBits((float)((TypeFloat)t).value());
+ add4(x);
+ }
+ }
+ }
+
// Patch local encodings now
private void patchLocalRelocations() {
// Walk the local code-address relocations