You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The compiler can be built with `go build`. Unit tests are run on the
45
48
host and on a ulp emulator, they can be run with `go test ./...`.
46
49
50
+
# Using ulp-forth
51
+
52
+
Help running the program can be found with `ulp-forth --help`.
53
+
54
+
## Running the interpreter
55
+
56
+
The interpreter can be run with `ulp-forth run`. This can be used for testing logic, but only runs on the host so cannot be used for testing hardware. Type `bye` to exit.
57
+
58
+
## Running the compiler
59
+
60
+
The cross compiler can be run with `ulp-forth build`. The user should pass in the list of files to be built, which will be interpreted in order before cross compiling the `MAIN` word. So `ulp-forth build first.f second.f` will first interpret first.f, then second.f, then cross compile the `MAIN` word.
61
+
62
+
## Compiler flags
63
+
64
+
*`--assembly` Output assembly that can be compiled by the main assemblers, set the --reserved flag before using.
65
+
*`--custom_assembly` Output assembly only for use by ulp-asm, another project by this author.
66
+
67
+
*`--output` Name of the output file.
68
+
*`--reserved` Number of reserved bytes for the ULP, for use with --assembly flag (default 8176). Note that the Espressif linker has a bug so has 12 less total bytes. Any space not used by code or data is used for the stacks.
69
+
*`--subroutine` Use the subroutine threading model, see the [threading models](#threading-models) section.
70
+
71
+
# Threading models
72
+
73
+
There are two threading models for the output ULP code. This is forth definition of "threading" and is not the same as multithreading in other languages. It can be thought of as the execution environment.
74
+
75
+
Token threading is usually smaller and subroutine threading is usually bigger, but this can vary based on the program and optimizations.
76
+
77
+
## Token threading (default)
78
+
79
+
This is the default threading model. This uses a lightweight virtual machine to execute all forth words. This allows for some very compact code, but there is a speed penalty for the virtual machine.
80
+
81
+
Code using this is roughly 20% smaller than subroutine threaded code.
82
+
83
+
## Subroutine threading
84
+
85
+
This can be enabled with the `--subroutine` flag. It copmiles all forth words into assembly subroutines. This is very fast while executing, but there is a size penalty.
86
+
87
+
Code using this is roughly 20% faster than token threaded code.
88
+
47
89
# Assembly words
48
90
49
91
A few words are provided to make ULP assembly without extending
@@ -105,6 +147,12 @@ Skip leading spaces. Parse `name` delimited by a space. Create an
105
147
assembly definition for `name` that writes to RTC address `addr0`
106
148
followed by address `addr1`.
107
149
150
+
## System words
151
+
152
+
`HALT` halts execution of the ULP. Execution will resume at the instruction immediately following the HALT on both token and subroutine threaded models.
153
+
154
+
`MUTEX.TAKE` and `MUTEX.GIVE` takes and gives the software mutex respectively. The example project includes esp32 code to use this but a better way to use it needs to be written.
155
+
108
156
# Clock words
109
157
110
158
The ULP has access to the RTC_SLOW clock. ulp-forth also has
@@ -388,8 +436,6 @@ error if it cannot be cannot be cross compiled.
388
436
* Can only run on host.
389
437
*`COUNT`
390
438
*`CR`
391
-
*`CREATE`
392
-
* Can only run on host.
393
439
*`DECIMAL`
394
440
*`DEPTH`
395
441
*`DO`
@@ -491,6 +537,7 @@ all can be in the future.
491
537
*`2LITERAL`
492
538
*`2VARIABLE`
493
539
*`D-`
540
+
*`D+`
494
541
*`D0<`
495
542
*`D0=`
496
543
*`D>S`
@@ -499,3 +546,18 @@ all can be in the future.
499
546
*`DMIN`
500
547
*`DNEGATE`
501
548
*`DU<`
549
+
550
+
# Optimizations
551
+
552
+
The cross compiler includes some optimizations. More may be added later.
553
+
554
+
* Inline deferred words. If a word is defined by `DEFER` but the deferred word cannot be changed by the cross compiled output, this will inline the word. Normally a deferred word will look like: `address-containing-word @ EXECUTE EXIT`, this optimizes that to: `word EXIT`.
555
+
* Tail calls. Words may be defined in assembly or forth. If the final word before an `EXIT` (or end of definition) is a forth word, this will instead jump to it. For example, a word that is compiled as `+ forth-word EXIT` will be optimized to `+ jump(forth-word)`. Smaller in token threaded model, faster, saves a stack slot.
buildCmd.Flags().String(CmdOutput, "", "Name of output file")
120
-
buildCmd.Flags().IntP(CmdReserved, "r", 8176, "Number of reserved bytes for the ULP, for use with --assembly flag")
119
+
buildCmd.Flags().String(CmdOutput, "", "Name of the output file.")
120
+
buildCmd.Flags().IntP(CmdReserved, "r", 8176, "Number of reserved bytes for the ULP, for use with --assembly flag. Note that the espressif linker reserves an extra 12 bytes.")
121
121
122
-
buildCmd.Flags().Bool(CmdAssembly, false, "Output assembly that can be compiled by the main assemblers, set the --reserved flag before using")
123
-
buildCmd.Flags().Bool(CmdCustomAssembly, false, "Output assembly only for use by ulp-asm")
122
+
buildCmd.Flags().Bool(CmdAssembly, false, "Output assembly that can be compiled by the main assemblers, set the --reserved flag before using.")
123
+
buildCmd.Flags().Bool(CmdCustomAssembly, false, "Output assembly only for use by ulp-asm, another project by this author.")
0 commit comments