From 887f3d9caf68b051c630bab6c8895778be8f044f Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Fri, 4 Apr 2025 12:29:46 -0700 Subject: Partial progress cpool in ELF Align functions to 16b --- .../com/seaofnodes/simple/codegen/ElfFile.java | 30 +++---- .../com/seaofnodes/simple/codegen/Encoding.java | 100 +++++++++++---------- 2 files changed, 64 insertions(+), 66 deletions(-) (limited to 'chapter21/src/main/java') 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 _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 _bigCons = new HashMap<>(); - public final HashMap _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 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 _cpool = new HashMap<>(); + public final BAOS _cbits = new BAOS(); + private void writeConstantPool(boolean elf) { + HashSet 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 -- cgit v1.2.3