projects
/
BearSSL
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
e61ad42
)
Optimised T0 generated code: when possible (at most 256 words), word calls are encode...
author
Thomas Pornin
<pornin@bolet.org>
Mon, 12 Dec 2016 18:58:49 +0000
(19:58 +0100)
committer
Thomas Pornin
<pornin@bolet.org>
Mon, 12 Dec 2016 18:58:49 +0000
(19:58 +0100)
T0/CodeElement.cs
patch
|
blob
|
history
T0/CodeElementJump.cs
patch
|
blob
|
history
T0/CodeElementUInt.cs
patch
|
blob
|
history
T0/CodeElementUIntExpr.cs
patch
|
blob
|
history
T0/CodeElementUIntInt.cs
patch
|
blob
|
history
T0/CodeElementUIntUInt.cs
patch
|
blob
|
history
T0/T0Comp.cs
patch
|
blob
|
history
T0Comp.exe
patch
|
blob
|
history
diff --git
a/T0/CodeElement.cs
b/T0/CodeElement.cs
index
5731c5a
..
471a61f
100644
(file)
--- a/
T0/CodeElement.cs
+++ b/
T0/CodeElement.cs
@@
-30,7
+30,7
@@
abstract class CodeElement {
internal int LastLength { get; set; }
internal int LastLength { get; set; }
- internal abstract int Length { get; }
+
//
internal abstract int Length { get; }
internal CodeElement()
{
internal CodeElement()
{
@@
-42,7
+42,19
@@
abstract class CodeElement {
throw new Exception("Code element accepts no target");
}
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)
{
internal static int Encode7EUnsigned(uint val, BlobWriter bw)
{
diff --git
a/T0/CodeElementJump.cs
b/T0/CodeElementJump.cs
index
5abd7eb
..
4dae0bc
100644
(file)
--- a/
T0/CodeElementJump.cs
+++ b/
T0/CodeElementJump.cs
@@
-34,6
+34,7
@@
class CodeElementJump : CodeElement {
this.jumpType = jumpType;
}
this.jumpType = jumpType;
}
+ /* obsolete
internal override int Length {
get {
int len = Encode7EUnsigned(jumpType, null);
internal override int Length {
get {
int len = Encode7EUnsigned(jumpType, null);
@@
-46,6
+47,19
@@
class CodeElementJump : CodeElement {
return len;
}
}
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)
{
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) {
{
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");
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
(file)
--- a/
T0/CodeElementUInt.cs
+++ b/
T0/CodeElementUInt.cs
@@
-33,14
+33,23
@@
class CodeElementUInt : CodeElement {
this.val = val;
}
this.val = val;
}
+ /* obsolete
internal override int Length {
get {
return Encode7EUnsigned(val, null);
}
}
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
(file)
--- a/
T0/CodeElementUIntExpr.cs
+++ b/
T0/CodeElementUIntExpr.cs
@@
-38,16
+38,26
@@
class CodeElementUIntExpr : CodeElement {
this.off = off;
}
this.off = off;
}
+ /* obsolete
internal override int Length {
get {
return Encode7EUnsigned(val, null)
+ (cx.GetMaxBitLength(off) + 6) / 7;
}
}
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)));
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
(file)
--- a/
T0/CodeElementUIntInt.cs
+++ b/
T0/CodeElementUIntInt.cs
@@
-35,16
+35,26
@@
class CodeElementUIntInt : CodeElement {
this.val2 = val2;
}
this.val2 = val2;
}
+ /* obsolete
internal override int Length {
get {
return Encode7EUnsigned(val1, null)
+ Encode7ESigned(val2, null);
}
}
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;
}
len += Encode7ESigned(val2, bw);
return len;
}
diff --git
a/T0/CodeElementUIntUInt.cs
b/T0/CodeElementUIntUInt.cs
index
3d4ee33
..
6f94de5
100644
(file)
--- a/
T0/CodeElementUIntUInt.cs
+++ b/
T0/CodeElementUIntUInt.cs
@@
-34,16
+34,26
@@
class CodeElementUIntUInt : CodeElement {
this.val2 = val2;
}
this.val2 = val2;
}
+ /* obsolete
internal override int Length {
get {
return Encode7EUnsigned(val1, null)
+ Encode7EUnsigned(val2, null);
}
}
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;
}
len += Encode7EUnsigned(val2, bw);
return len;
}
diff --git
a/T0/T0Comp.cs
b/T0/T0Comp.cs
index
143badb
..
20adc04
100644
(file)
--- a/
T0/T0Comp.cs
+++ b/
T0/T0Comp.cs
@@
-1626,6
+1626,20
@@
public class T0Comp {
}
CodeElement[] gcode = gcodeList.ToArray();
}
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.
/*
* 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 ++) {
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 ++) {
}
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) {
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("};");
}
tw.WriteLine();
tw.WriteLine("};");
@@
-1805,6
+1819,14
@@
name(void *ctx) \
wordSet[ep].Slot);
}
tw.WriteLine();
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}",
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_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;
dp = ((t0_context *)t0ctx)->dp;
rp = ((t0_context *)t0ctx)->rp;
ip = ((t0_context *)t0ctx)->ip;
+ goto t0_next;
for (;;) {
uint32_t t0x;
for (;;) {
uint32_t t0x;
- t0x = t0_parse7E_unsigned(&ip);
+ t0_next:
+ t0x = T0_NEXT(&ip);
if (t0x < T0_INTERPRETED) {
switch (t0x) {
int32_t t0off;
if (t0x < T0_INTERPRETED) {
switch (t0x) {
int32_t t0off;
@@
-1932,7
+1956,7
@@
t0_exit:
int codeLen = 0;
foreach (CodeElement ce in gcode) {
int codeLen = 0;
foreach (CodeElement ce in gcode) {
- codeLen += ce.
Length
;
+ codeLen += ce.
GetLength(oneByteCode)
;
}
int dataBlockLen = 0;
foreach (ConstData cd in blocks.Values) {
}
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("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)
}
internal Word Lookup(string name)
diff --git
a/T0Comp.exe
b/T0Comp.exe
index
411645c
..
b951fab
100755
(executable)
Binary files a/T0Comp.exe and b/T0Comp.exe differ