// Copyright 2011-2021 XMOS LIMITED. // This Software is subject to the terms of the XMOS Public Licence: Version 1. import java.io.*; import java.util.*; class Arrange { String labels[] = { // "L11d", // "L1d", // "L111d", "L1000", "L100", "L10", "L11100", "L11000", "L1110", "L1100", "L110", "L111", "L1111", "L11111", "L11111a", "L1111111", "L111111", "L1", "L11", "L1_S", "L11100_S", "L11_S", "L111_S", "L1111_S", "L11111_S", "L111111_S", "L1111111_S", "L1_U", "L11_U", "L111_U", "L1111_U", "L11111_U", "L111111_U", "L1111111_U", "L1_T", "L11_T", "L111_T", // "L1110_S", "L1111100_S", "L111110_S", }; static HashMap entryPoints = new HashMap(); static Vector blockVector = new Vector(); static int blockCount = 0; static int cutOff = 50; static Block error =null; void run() { entryPoints.put("ERROR", new Block("ERROR", -1)); entryPoints.put("FASTER", new Block("FASTER", -2)); entryPoints.put("SLOWER", error = new Block("SLOWER", -3)); for (String s: labels) { Block b = new Block(s, blockCount); blockVector.add(b); blockCount++; b = new Block(b, blockCount); blockVector.add(b); blockCount++; } for(Block b: blockVector) { b.patchReferences(); } for(Block b: blockVector) { if (!b.used) { System.err.println("No reference to " + b.bbName); } } for(int i = 0; i < 15; i++) { // 15 optimise(20); // 20 System.err.println("Cost " + cost() + " (cutoff " + cutOff + ")"); if (cost() < 100000) { cutOff--; } } copy("headerS"); for(Block b: blockVector) { System.out.println(b.theCode()); } copy("trailerS"); } int cost() { int costs = 0; for(int loc = 0; loc < blockCount; loc++) { Block b = blockVector.get(loc); costs += b.cost(); } return costs; } void swapBlocks(int j, int k) { Block a = blockVector.get(j); Block b = blockVector.get(k); blockVector.set(j, b); blockVector.set(k, a); a.location = k; b.location = j; } void optimise(int n) { int minCost = cost(); int minJ = -1; int minK = -1; for(int i = 0; i < n; i++) { System.err.println(" -- Cost " + minCost); for(int j = 0; j < blockCount; j++) { for(int k = j+1; k < blockCount; k++) { swapBlocks(j, k); if (cost() < minCost) { minJ = j; minK = k; minCost = cost(); } swapBlocks(j, k); } } if (minJ != -1) { swapBlocks(minJ, minK); } else { break; } if (minCost < 100000) { break; } } } void copy(String s) { try { BufferedReader bi = new BufferedReader(new FileReader("states/" + s)); while(true) { String line = bi.readLine(); if (line == null) { return; } System.out.println(line); } } catch (Exception e) { System.err.println("Exception " + e + " on " + s); } } public static void main(String args[]) { new Arrange().run(); } } class Block { Vector refs = new Vector(); Vector refsI = new Vector(); String bbName; int location; boolean used = false; String code = ""; Block(String s, int location) { boolean beforeBru= true; bbName = s; this.location = location; if (!s.startsWith("L")) { return; } try { BufferedReader bi = new BufferedReader(new FileReader("states/" + s)); while(true) { String line = bi.readLine(); if (line == null) { return; } if (beforeBru) { code = code + line + "\n"; } if (line.contains("BRU")) { beforeBru= false; } if (line.contains(":")) { addEntrypoint(line,this); } if (!beforeBru) { if (line.contains("SLOWER")) { addReference("SLOWER"); } else if (line.contains("FASTER")) { addReference("FASTER"); } else if (line.contains("ERROR")) { addReference("ERROR"); } else if ((line.contains(" BL") || line.contains(" BR")) && line.contains(" L")) { addReference(line); } } } } catch (Exception e) { System.err.println("Exception " + e + " in " + s); } } Block(Block b, int location) { bbName = inverse(b.bbName); String lines[] = b.code.split("\n"); for(String l: lines) { if (l.contains(":")) { String i = inverse(l); code += i + "\n"; addEntrypoint(i,this); } else if (l.contains(" bf ") || l.contains(" bt ") || l.contains(" bu ") ) { code += inverse(l) + "\n"; } else if (l.contains(" BR")) { code += inverse(l) + "\n"; } else { code += l + "\n"; } } this.location = location; for(String s: b.refsI) { refsI.add(0, inverse(s)); } } String inverse(String s) { boolean inversing = true; String r = ""; for(int i = 0; i < s.length(); i++) { if (inversing && s.charAt(i) == '0') { r += '1'; } else if (inversing && s.charAt(i) == '1') { r += '0'; } else if (s.charAt(i) == '_') { r += '_'; inversing = false; } else { r += s.charAt(i); } } return r; } void addEntrypoint(String line, Block b) { String label = line.replaceAll(".* L","L").replaceAll(":.*",""); Arrange.entryPoints.put(label, b); } void addReference(String line) { String label1 = line.replaceFirst(".* L","L").replaceAll("[ /].*",""); String label = label1.replaceAll("[ /].*","").replaceAll("z",""); // System.out.println("Line " + line + " label " + label1 + " -- " + label); refsI.add(label); } void patchReferences() { for(String s: refsI) { Block b = Arrange.entryPoints.get(s); if (b == null) { System.err.println("Label " + s + " not found in " + bbName); refs.add(Arrange.error); } else { // System.err.println("Label " + s + " found in " + bbName); b.used = true; refs.add(b); } } } int cost() { int costs = 0; for(Block b: refs) { if (b.location < 0) { continue; } int c = location - b.location; if (c < 0) { c = -c; } if (c > Arrange.cutOff) { c += 100000; } costs += c; } return costs; } String theCode() { int k =0; for(Block b : refs) { if (b.location < 0) { if (location < Arrange.blockCount / 2) { code += " BLRB_u10 B" + b.bbName + "\n"; } else { code += " BLRF_u10 F" + b.bbName + "\n"; } } else if (b.location <= location) { code += " BLRB_u10 " + refsI.get(k) + "\n"; } else { code += " BLRF_u10 " + refsI.get(k) + "\n"; } k++; } return code; } }