From fb7052216d8cb257e47de57e615c3a2f573174de Mon Sep 17 00:00:00 2001 From: Thomas Pornin Date: Mon, 12 Dec 2016 19:58:49 +0100 Subject: [PATCH] Optimised T0 generated code: when possible (at most 256 words), word calls are encoded over one byte, even in the 128..255 range. --- T0/CodeElement.cs | 16 ++++++++++++++-- T0/CodeElementJump.cs | 25 ++++++++++++++++++++++--- T0/CodeElementUInt.cs | 13 +++++++++++-- T0/CodeElementUIntExpr.cs | 14 ++++++++++++-- T0/CodeElementUIntInt.cs | 14 ++++++++++++-- T0/CodeElementUIntUInt.cs | 14 ++++++++++++-- T0/T0Comp.cs | 38 +++++++++++++++++++++++++++++++------- T0Comp.exe | Bin 71680 -> 72704 bytes 8 files changed, 114 insertions(+), 20 deletions(-) diff --git a/T0/CodeElement.cs b/T0/CodeElement.cs index 5731c5a..471a61f 100644 --- a/T0/CodeElement.cs +++ b/T0/CodeElement.cs @@ -30,7 +30,7 @@ abstract class CodeElement { internal int LastLength { get; set; } - internal abstract int Length { get; } + // internal abstract int Length { get; } internal CodeElement() { @@ -42,7 +42,19 @@ abstract class CodeElement { throw new Exception("Code element accepts no target"); } - internal abstract int Encode(BlobWriter bw); + internal abstract int GetLength(bool oneByteCode); + + internal abstract int Encode(BlobWriter bw, bool oneByteCode); + + internal static int EncodeOneByte(uint val, BlobWriter bw) + { + if (val > 255) { + throw new Exception(string.Format( + "Cannot encode '{0}' over one byte", val)); + } + bw.Append((byte)val); + return 1; + } internal static int Encode7EUnsigned(uint val, BlobWriter bw) { diff --git a/T0/CodeElementJump.cs b/T0/CodeElementJump.cs index 5abd7eb..4dae0bc 100644 --- a/T0/CodeElementJump.cs +++ b/T0/CodeElementJump.cs @@ -34,6 +34,7 @@ class CodeElementJump : CodeElement { this.jumpType = jumpType; } + /* obsolete internal override int Length { get { int len = Encode7EUnsigned(jumpType, null); @@ -46,6 +47,19 @@ class CodeElementJump : CodeElement { return len; } } + */ + + internal override int GetLength(bool oneByteCode) + { + int len = oneByteCode ? 1 : Encode7EUnsigned(jumpType, null); + int joff = JumpOff; + if (joff == Int32.MinValue) { + len ++; + } else { + len += Encode7ESigned(joff, null); + } + return len; + } internal override void SetJumpTarget(CodeElement target) { @@ -63,12 +77,17 @@ class CodeElementJump : CodeElement { } } - internal override int Encode(BlobWriter bw) + internal override int Encode(BlobWriter bw, bool oneByteCode) { if (bw == null) { - return Length; + return GetLength(oneByteCode); + } + int len; + if (oneByteCode) { + len = EncodeOneByte(jumpType, bw); + } else { + len = Encode7EUnsigned(jumpType, bw); } - int len = Encode7EUnsigned(jumpType, bw); int joff = JumpOff; if (joff == Int32.MinValue) { throw new Exception("Unresolved addresses"); diff --git a/T0/CodeElementUInt.cs b/T0/CodeElementUInt.cs index e5f3607..049cdad 100644 --- a/T0/CodeElementUInt.cs +++ b/T0/CodeElementUInt.cs @@ -33,14 +33,23 @@ class CodeElementUInt : CodeElement { this.val = val; } + /* obsolete internal override int Length { get { return Encode7EUnsigned(val, null); } } + */ - internal override int Encode(BlobWriter bw) + internal override int GetLength(bool oneByteCode) { - return Encode7EUnsigned(val, bw); + return oneByteCode ? 1 : Encode7EUnsigned(val, null); + } + + internal override int Encode(BlobWriter bw, bool oneByteCode) + { + return oneByteCode + ? EncodeOneByte(val, bw) + : Encode7EUnsigned(val, bw); } } diff --git a/T0/CodeElementUIntExpr.cs b/T0/CodeElementUIntExpr.cs index d24ba58..8dd55a5 100644 --- a/T0/CodeElementUIntExpr.cs +++ b/T0/CodeElementUIntExpr.cs @@ -38,16 +38,26 @@ class CodeElementUIntExpr : CodeElement { this.off = off; } + /* obsolete internal override int Length { get { return Encode7EUnsigned(val, null) + (cx.GetMaxBitLength(off) + 6) / 7; } } + */ - internal override int Encode(BlobWriter bw) + internal override int GetLength(bool oneByteCode) { - int len1 = Encode7EUnsigned(val, bw); + int len = oneByteCode ? 1 : Encode7EUnsigned(val, null); + return len + (cx.GetMaxBitLength(off) + 6) / 7; + } + + internal override int Encode(BlobWriter bw, bool oneByteCode) + { + int len1 = oneByteCode + ? EncodeOneByte(val, bw) + : Encode7EUnsigned(val, bw); int len2 = (cx.GetMaxBitLength(off) + 6) / 7; bw.Append(String.Format("T0_INT{0}({1})", len2, cx.ToCExpr(off))); diff --git a/T0/CodeElementUIntInt.cs b/T0/CodeElementUIntInt.cs index 022ffb8..0223e27 100644 --- a/T0/CodeElementUIntInt.cs +++ b/T0/CodeElementUIntInt.cs @@ -35,16 +35,26 @@ class CodeElementUIntInt : CodeElement { this.val2 = val2; } + /* obsolete internal override int Length { get { return Encode7EUnsigned(val1, null) + Encode7ESigned(val2, null); } } + */ - internal override int Encode(BlobWriter bw) + internal override int GetLength(bool oneByteCode) { - int len = Encode7EUnsigned(val1, bw); + return (oneByteCode ? 1 : Encode7EUnsigned(val1, null)) + + Encode7ESigned(val2, null); + } + + internal override int Encode(BlobWriter bw, bool oneByteCode) + { + int len = oneByteCode + ? EncodeOneByte(val1, bw) + : Encode7EUnsigned(val1, bw); len += Encode7ESigned(val2, bw); return len; } diff --git a/T0/CodeElementUIntUInt.cs b/T0/CodeElementUIntUInt.cs index 3d4ee33..6f94de5 100644 --- a/T0/CodeElementUIntUInt.cs +++ b/T0/CodeElementUIntUInt.cs @@ -34,16 +34,26 @@ class CodeElementUIntUInt : CodeElement { this.val2 = val2; } + /* obsolete internal override int Length { get { return Encode7EUnsigned(val1, null) + Encode7EUnsigned(val2, null); } } + */ - internal override int Encode(BlobWriter bw) + internal override int GetLength(bool oneByteCode) { - int len = Encode7EUnsigned(val1, bw); + return (oneByteCode ? 1 : Encode7EUnsigned(val1, null)) + + Encode7EUnsigned(val2, null); + } + + internal override int Encode(BlobWriter bw, bool oneByteCode) + { + int len = oneByteCode + ? EncodeOneByte(val1, bw) + : Encode7EUnsigned(val1, bw); len += Encode7EUnsigned(val2, bw); return len; } diff --git a/T0/T0Comp.cs b/T0/T0Comp.cs index 143badb..20adc04 100644 --- a/T0/T0Comp.cs +++ b/T0/T0Comp.cs @@ -1626,6 +1626,20 @@ public class T0Comp { } CodeElement[] gcode = gcodeList.ToArray(); + /* + * If there are less than 256 words in total (C + + * interpreted) then we can use "one-byte code" which is + * more compact when the number of words is in the + * 128..255 range. + */ + bool oneByteCode; + if (slotInterpreted + numInterpreted >= 256) { + Console.WriteLine("WARNING: more than 255 words"); + oneByteCode = false; + } else { + oneByteCode = true; + } + /* * Compute all addresses and offsets. This loops until * the addresses stabilize. @@ -1634,7 +1648,7 @@ public class T0Comp { int[] gcodeLen = new int[gcode.Length]; for (;;) { for (int i = 0; i < gcode.Length; i ++) { - gcodeLen[i] = gcode[i].Length; + gcodeLen[i] = gcode[i].GetLength(oneByteCode); } int off = 0; for (int i = 0; i < gcode.Length; i ++) { @@ -1756,7 +1770,7 @@ static const uint8_t t0_datablock[]; tw.Write("static const uint8_t t0_codeblock[] = {"); bw = new BlobWriter(tw, 78, 1); foreach (CodeElement ce in gcode) { - ce.Encode(bw); + ce.Encode(bw, oneByteCode); } tw.WriteLine(); tw.WriteLine("};"); @@ -1805,6 +1819,14 @@ name(void *ctx) \ wordSet[ep].Slot); } tw.WriteLine(); + if (oneByteCode) { + tw.WriteLine("{0}", +@"#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++)"); + } else { + tw.WriteLine("{0}", +@"#define T0_NEXT(t0ipp) t0_parse7E_unsigned(t0ipp)"); + } + tw.WriteLine(); tw.WriteLine("void"); tw.WriteLine("{0}_run(void *t0ctx)", coreRun); tw.WriteLine("{0}", @@ -1853,15 +1875,17 @@ name(void *ctx) \ #define T0_CO() do { \ goto t0_exit; \ } while (0) -#define T0_RET() break +#define T0_RET() goto t0_next dp = ((t0_context *)t0ctx)->dp; rp = ((t0_context *)t0ctx)->rp; ip = ((t0_context *)t0ctx)->ip; + goto t0_next; for (;;) { uint32_t t0x; - t0x = t0_parse7E_unsigned(&ip); + t0_next: + t0x = T0_NEXT(&ip); if (t0x < T0_INTERPRETED) { switch (t0x) { int32_t t0off; @@ -1932,7 +1956,7 @@ t0_exit: int codeLen = 0; foreach (CodeElement ce in gcode) { - codeLen += ce.Length; + codeLen += ce.GetLength(oneByteCode); } int dataBlockLen = 0; foreach (ConstData cd in blocks.Values) { @@ -1944,8 +1968,8 @@ t0_exit: */ Console.WriteLine("code length: {0,6} byte(s)", codeLen); Console.WriteLine("data length: {0,6} byte(s)", dataLen); - Console.WriteLine("interpreted words: {0}", - interpretedEntry.Length); + Console.WriteLine("total words: {0} (interpreted: {1})", + slotInterpreted + numInterpreted, numInterpreted); } internal Word Lookup(string name) diff --git a/T0Comp.exe b/T0Comp.exe index 411645c0cf09792162e334169d500bc3ec3ca9bc..b951fab61f98888351a845a22f5e0d3b8a6ca4d7 100755 GIT binary patch delta 26461 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 a4dsi^&For%TQgB*pGWPe_*87K_5L5d9$QWT delta 25746 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 aquSR-W|@ZD5I$ZVdY@IOeXeb<_WnO|Ko-FO -- 2.17.1