X-Git-Url: https://www.bearssl.org/gitweb//home/git/?p=BearSSL;a=blobdiff_plain;f=T0%2FT0Comp.cs;h=7a397f7cbc487ab5098c0abeb58d961b69eeefe0;hp=143badb5dd88a06ead7e28a8d5f20bb3f6dd2e77;hb=d592e999329b4a661e5660d56e3226b73a2ad364;hpb=3210f38e0491b39aec1ef419cb4114e9483089fb diff --git a/T0/T0Comp.cs b/T0/T0Comp.cs index 143badb..7a397f7 100644 --- a/T0/T0Comp.cs +++ b/T0/T0Comp.cs @@ -251,6 +251,12 @@ public class T0Comp { */ List extraCode; + /* + * 'extraCodeDefer' is for C code that is to be added in the C + * output _after_ the data and code blocks. + */ + List extraCodeDefer; + /* * 'dataBlock' is the data block in which constant data bytes * are accumulated. @@ -287,6 +293,7 @@ public class T0Comp { StringComparer.Ordinal); compiling = false; extraCode = new List(); + extraCodeDefer = new List(); enableFlowAnalysis = true; /* @@ -348,6 +355,15 @@ public class T0Comp { extraCode.Add(ParseCCode()); }); + /* + * postamble + * Parses a C code snippet, then adds it to the generated + * output after the data and code blocks. + */ + AddNative("postamble", false, SType.BLANK, cpu => { + extraCodeDefer.Add(ParseCCode()); + }); + /* * make-CX * Expects two integers and a string, and makes a @@ -1626,6 +1642,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 +1664,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 ++) { @@ -1715,7 +1745,7 @@ t0_parse7E_signed(const unsigned char **p) #define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) #define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) -static const uint8_t t0_datablock[]; +/* static const unsigned char t0_datablock[]; */ "); /* @@ -1743,7 +1773,8 @@ static const uint8_t t0_datablock[]; BlobWriter bw; tw.WriteLine(); - tw.Write("static const uint8_t t0_datablock[] = {"); + tw.Write("static const unsigned char" + + " t0_datablock[] = {"); bw = new BlobWriter(tw, 78, 1); bw.Append((byte)0); foreach (ConstData cd in blocks.Values) { @@ -1753,10 +1784,11 @@ static const uint8_t t0_datablock[]; tw.WriteLine("};"); tw.WriteLine(); - tw.Write("static const uint8_t t0_codeblock[] = {"); + tw.Write("static const unsigned char" + + " 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 +1837,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 +1893,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; @@ -1928,11 +1970,22 @@ t0_exit: ((t0_context *)t0ctx)->rp = rp; ((t0_context *)t0ctx)->ip = ip; }"); + + /* + * Add the "postamblr" elements here. These are + * elements that may need access to the data + * block or code block, so they must occur after + * their definition. + */ + foreach (string pp in extraCodeDefer) { + tw.WriteLine(); + tw.WriteLine("{0}", pp); + } } 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 +1997,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)