diff options
author | Kartik Agaram <vc@akkartik.com> | 2020-10-01 00:46:38 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2020-10-01 00:46:38 -0700 |
commit | 3d053e34b71832b38d77bb777e7acabcb1e63e76 (patch) | |
tree | 374b1c32ebe5cfb6d3a12bb228f44a2c7cb62471 | |
parent | df04b364a689a4eb970087da253e93fb6ee3f22d (diff) | |
download | mu-3d053e34b71832b38d77bb777e7acabcb1e63e76.tar.gz |
6919
-rw-r--r-- | html/mu_instructions.html | 104 |
1 files changed, 98 insertions, 6 deletions
diff --git a/html/mu_instructions.html b/html/mu_instructions.html index 0c66bc97..3a2313c5 100644 --- a/html/mu_instructions.html +++ b/html/mu_instructions.html @@ -60,6 +60,7 @@ var/reg <span class="SpecialChar"><-</span> add var2/reg2 => <spa var/reg <span class="SpecialChar"><-</span> add var2 => <span class="Constant">"03/add *(ebp+"</span> var2.stack-offset <span class="Constant">") "</span> reg <span class="Constant">"/r32"</span> var/reg <span class="SpecialChar"><-</span> add *var2/reg2 => <span class="Constant">"03/add *"</span> reg2 <span class="Constant">" "</span> reg <span class="Constant">"/r32"</span> add-to var1, var2/reg => <span class="Constant">"01/add-to *(ebp+"</span> var1.stack-offset <span class="Constant">") "</span> reg <span class="Constant">"/r32"</span> +add-to *var1/reg1, var2/reg2 => <span class="Constant">"01/add-to *"</span> reg1 <span class="Constant">" "</span> reg2 <span class="Constant">"/r32"</span> var/<span class="Constant">eax</span> <span class="SpecialChar"><-</span> add n => <span class="Constant">"05/add-to-eax "</span> n <span class="Constant">"/imm32"</span> var/reg <span class="SpecialChar"><-</span> add n => <span class="Constant">"81 0/subop/add %"</span> reg <span class="Constant">" "</span> n <span class="Constant">"/imm32"</span> add-to var, n => <span class="Constant">"81 0/subop/add *(ebp+"</span> var.stack-offset <span class="Constant">") "</span> n <span class="Constant">"/imm32"</span> @@ -69,6 +70,7 @@ var/reg <span class="SpecialChar"><-</span> subtract var2/reg2 => <spa var/reg <span class="SpecialChar"><-</span> subtract var2 => <span class="Constant">"2b/subtract *(ebp+"</span> var2.stack-offset <span class="Constant">") "</span> reg <span class="Constant">"/r32"</span> var/reg <span class="SpecialChar"><-</span> subtract *var2/reg2 => <span class="Constant">"2b/subtract *"</span> reg2 <span class="Constant">" "</span> reg1 <span class="Constant">"/r32"</span> subtract-from var1, var2/reg2 => <span class="Constant">"29/subtract-from *(ebp+"</span> var1.stack-offset <span class="Constant">") "</span> reg2 <span class="Constant">"/r32"</span> +subtract-from *var1/reg1, var2/reg2 => <span class="Constant">"29/subtract-from *"</span> reg1 <span class="Constant">" "</span> reg2 <span class="Constant">"/r32"</span> var/<span class="Constant">eax</span> <span class="SpecialChar"><-</span> subtract n => <span class="Constant">"2d/subtract-from-eax "</span> n <span class="Constant">"/imm32"</span> var/reg <span class="SpecialChar"><-</span> subtract n => <span class="Constant">"81 5/subop/subtract %"</span> reg <span class="Constant">" "</span> n <span class="Constant">"/imm32"</span> subtract-from var, n => <span class="Constant">"81 5/subop/subtract *(ebp+"</span> var.stack-offset <span class="Constant">") "</span> n <span class="Constant">"/imm32"</span> @@ -78,6 +80,7 @@ var/reg <span class="SpecialChar"><-</span> and var2/reg2 => <spa var/reg <span class="SpecialChar"><-</span> and var2 => <span class="Constant">"23/and *(ebp+"</span> var2.stack-offset <span class="Constant">" "</span> reg <span class="Constant">"/r32"</span> var/reg <span class="SpecialChar"><-</span> and *var2/reg2 => <span class="Constant">"23/and *"</span> reg2 <span class="Constant">" "</span> reg <span class="Constant">"/r32"</span> and-with var1, var2/reg => <span class="Constant">"21/and-with *(ebp+"</span> var1.stack-offset <span class="Constant">") "</span> reg <span class="Constant">"/r32"</span> +and-with *var1/reg1, var2/reg2 => <span class="Constant">"21/and-with *"</span> reg1 <span class="Constant">" "</span> reg2 <span class="Constant">"/r32"</span> var/<span class="Constant">eax</span> <span class="SpecialChar"><-</span> and n => <span class="Constant">"25/and-with-eax "</span> n <span class="Constant">"/imm32"</span> var/reg <span class="SpecialChar"><-</span> and n => <span class="Constant">"81 4/subop/and %"</span> reg <span class="Constant">" "</span> n <span class="Constant">"/imm32"</span> and-with var, n => <span class="Constant">"81 4/subop/and *(ebp+"</span> var.stack-offset <span class="Constant">") "</span> n <span class="Constant">"/imm32"</span> @@ -87,6 +90,7 @@ var/reg <span class="SpecialChar"><-</span> or var2/reg2 => <spa var/reg <span class="SpecialChar"><-</span> or var2 => <span class="Constant">"0b/or *(ebp+"</span> var2.stack-offset <span class="Constant">") "</span> reg <span class="Constant">"/r32"</span> var/reg <span class="SpecialChar"><-</span> or *var2/reg2 => <span class="Constant">"0b/or *"</span> reg2 <span class="Constant">" "</span> reg <span class="Constant">"/r32"</span> or-with var1, var2/reg2 => <span class="Constant">"09/or-with *(ebp+"</span> var1.stack-offset <span class="Constant">" "</span> reg2 <span class="Constant">"/r32"</span> +or-with *var1/reg1, var2/reg2 => <span class="Constant">"09/or-with *"</span> reg1 <span class="Constant">" "</span> reg2 <span class="Constant">"/r32"</span> var/<span class="Constant">eax</span> <span class="SpecialChar"><-</span> or n => <span class="Constant">"0d/or-with-eax "</span> n <span class="Constant">"/imm32"</span> var/reg <span class="SpecialChar"><-</span> or n => <span class="Constant">"81 1/subop/or %"</span> reg <span class="Constant">" "</span> n <span class="Constant">"/imm32"</span> or-with var, n => <span class="Constant">"81 1/subop/or *(ebp+"</span> var.stack-offset <span class="Constant">") "</span> n <span class="Constant">"/imm32"</span> @@ -96,17 +100,21 @@ var/reg <span class="SpecialChar"><-</span> xor var2/reg2 => <spa var/reg <span class="SpecialChar"><-</span> xor var2 => <span class="Constant">"33/xor *(ebp+"</span> var2.stack-offset <span class="Constant">") "</span> reg <span class="Constant">"/r32"</span> var/reg <span class="SpecialChar"><-</span> xor *var2/reg2 => <span class="Constant">"33/xor *"</span> reg2 <span class="Constant">" "</span> reg <span class="Constant">"/r32"</span> xor-with var1, var2/reg => <span class="Constant">"31/xor-with *(ebp+"</span> var1.stack-offset <span class="Constant">") "</span> reg <span class="Constant">"/r32"</span> +xor-with *var1/reg1, var2/reg2 => <span class="Constant">"31/xor-with *"</span> reg1 <span class="Constant">" "</span> reg2 <span class="Constant">"/r32"</span> var/<span class="Constant">eax</span> <span class="SpecialChar"><-</span> xor n => <span class="Constant">"35/xor-with-eax "</span> n <span class="Constant">"/imm32"</span> var/reg <span class="SpecialChar"><-</span> xor n => <span class="Constant">"81 6/subop/xor %"</span> reg <span class="Constant">" "</span> n <span class="Constant">"/imm32"</span> xor-with var, n => <span class="Constant">"81 6/subop/xor *(ebp+"</span> var.stack-offset <span class="Constant">") "</span> n <span class="Constant">"/imm32"</span> xor-with *var/reg, n => <span class="Constant">"81 6/subop/xor *"</span> reg <span class="Constant">" "</span> n <span class="Constant">"/imm32"</span> -var/reg <span class="SpecialChar"><-</span> shift-left n -var/reg <span class="SpecialChar"><-</span> shift-right n -var/reg <span class="SpecialChar"><-</span> shift-right-signed n -shift-left var, n -shift-right var, n -shift-right-signed var, n +var/reg <span class="SpecialChar"><-</span> shift-left n => <span class="Constant">"c1/shift 4/subop/left %"</span> reg <span class="Constant">" "</span> n <span class="Constant">"/imm32"</span> +var/reg <span class="SpecialChar"><-</span> shift-right n => <span class="Constant">"c1/shift 5/subop/right %"</span> reg <span class="Constant">" "</span> n <span class="Constant">"/imm32"</span> +var/reg <span class="SpecialChar"><-</span> shift-right-signed n => <span class="Constant">"c1/shift 7/subop/right-signed %"</span> reg <span class="Constant">" "</span> n <span class="Constant">"/imm32"</span> +shift-left var, n => <span class="Constant">"c1/shift 4/subop/left *(ebp+"</span> var.stack-offset <span class="Constant">") "</span> n <span class="Constant">"/imm32"</span> +shift-left *var/reg, n => <span class="Constant">"c1/shift 4/subop/left *"</span> reg <span class="Constant">" "</span> n <span class="Constant">"/imm32"</span> +shift-right var, n => <span class="Constant">"c1/shift 5/subop/right *(ebp+"</span> var.stack-offset <span class="Constant">") "</span> n <span class="Constant">"/imm32"</span> +shift-right *var/reg, n => <span class="Constant">"c1/shift 5/subop/right *"</span> reg <span class="Constant">" "</span> n <span class="Constant">"/imm32"</span> +shift-right-signed var, n => <span class="Constant">"c1/shift 7/subop/right-signed *(ebp+"</span> var.stack-offset <span class="Constant">") "</span> n <span class="Constant">"/imm32"</span> +shift-right-signed *var/reg, n => <span class="Constant">"c1/shift 7/subop/right-signed *"</span> reg <span class="Constant">" "</span> n <span class="Constant">"/imm32"</span> var/<span class="Constant">eax</span> <span class="SpecialChar"><-</span> copy n => <span class="Constant">"b8/copy-to-eax "</span> n <span class="Constant">"/imm32"</span> var/<span class="Constant">ecx</span> <span class="SpecialChar"><-</span> copy n => <span class="Constant">"b9/copy-to-ecx "</span> n <span class="Constant">"/imm32"</span> @@ -116,6 +124,7 @@ var/<span class="Constant">esi</span> <span class="SpecialChar"><-</span> cop var/<span class="Constant">edi</span> <span class="SpecialChar"><-</span> copy n => <span class="Constant">"bf/copy-to-edi "</span> n <span class="Constant">"/imm32"</span> var/reg <span class="SpecialChar"><-</span> copy var2/reg2 => <span class="Constant">"89/<- %"</span> reg <span class="Constant">" "</span> reg2 <span class="Constant">"/r32"</span> copy-to var1, var2/reg => <span class="Constant">"89/<- *(ebp+"</span> var1.stack-offset <span class="Constant">") "</span> reg <span class="Constant">"/r32"</span> +copy-to *var1/reg1, var2/reg2 => <span class="Constant">"89/<- *"</span> reg1 <span class="Constant">" "</span> reg2 <span class="Constant">"/r32"</span> var/reg <span class="SpecialChar"><-</span> copy var2 => <span class="Constant">"8b/-> *(ebp+"</span> var2.stack-offset <span class="Constant">") "</span> reg <span class="Constant">"/r32"</span> var/reg <span class="SpecialChar"><-</span> copy *var2/reg2 => <span class="Constant">"8b/-> *"</span> reg2 <span class="Constant">" "</span> reg <span class="Constant">"/r32"</span> var/reg <span class="SpecialChar"><-</span> copy n => <span class="Constant">"c7 0/subop/copy %"</span> reg <span class="Constant">" "</span> n <span class="Constant">"/imm32"</span> @@ -193,6 +202,12 @@ var/reg <span class="SpecialChar"><-</span> multiply *var2/reg2 => <spa <span class="PreProc">loop-if-addr>=</span> => <span class="Constant">"0f 83/jump-if-addr>= loop/disp32"</span> <span class="PreProc">loop-if-addr>=</span> label => <span class="Constant">"0f 83/jump-if-addr>= "</span> label <span class="Constant">":loop/disp32"</span> +Similar float variants like `<span class="PreProc">break-if-loop<`</span> are aliases for the corresponding +`addr` equivalents. The x86 instruction set stupidly has floating-point +operations only update a subset of flags. + +--- + In the following instructions types are provided for clarity even if they must be provided in an earlier 'var' declaration. @@ -278,6 +293,83 @@ read-from-stream s: (addr stream T), out: (addr T) write-to-stream s: (addr stream T), in: (addr T) => <span class="Constant">"(write-to-stream "</span> s <span class="Constant">" "</span> in <span class="Constant">" "</span> size-of(T) <span class="Constant">")"</span> +<span class="Comment"># Floating-point operations</span> + +All the instructions so far use Intel's general-purpose integer registers. +However, some of them translate to different SubX if their arguments are in +floating-point registers. + +var/xreg <span class="SpecialChar"><-</span> add var2/xreg2 => <span class="Constant">"f3 0f 58/add 3/mod "</span> xreg2 <span class="Constant">"/xm32 "</span> xreg1 <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> add var2 => <span class="Constant">"f3 0f 58/add *(ebp+"</span> var2.stack-offset <span class="Constant">") "</span> xreg <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> add *var2/reg2 => <span class="Constant">"f3 0f 58/add *"</span> reg2 <span class="Constant">" "</span> xreg <span class="Constant">"/x32"</span> + +var/xreg <span class="SpecialChar"><-</span> subtract var2/xreg2 => <span class="Constant">"f3 0f 5c/subtract 3/mod "</span> xreg2 <span class="Constant">"/xm32 "</span> xreg1 <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> subtract var2 => <span class="Constant">"f3 0f 5c/subtract *(ebp+"</span> var2.stack-offset <span class="Constant">") "</span> xreg <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> subtract *var2/reg2 => <span class="Constant">"f3 0f 5c/subtract *"</span> reg2 <span class="Constant">" "</span> xreg <span class="Constant">"/x32"</span> + +var/xreg <span class="SpecialChar"><-</span> multiply var2/xreg2 => <span class="Constant">"f3 0f 59/multiply 3/mod "</span> xreg2 <span class="Constant">"/xm32 "</span> xreg1 <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> multiply var2 => <span class="Constant">"f3 0f 59/multiply *(ebp+"</span> var2.stack-offset <span class="Constant">") "</span> xreg <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> multiply *var2/reg2 => <span class="Constant">"f3 0f 59/multiply *"</span> reg2 <span class="Constant">" "</span> xreg <span class="Constant">"/x32"</span> + +var/xreg <span class="SpecialChar"><-</span> divide var2/xreg2 => <span class="Constant">"f3 0f 5e/divide 3/mod "</span> xreg2 <span class="Constant">"/xm32 "</span> xreg1 <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> divide var2 => <span class="Constant">"f3 0f 5e/divide *(ebp+"</span> var2.stack-offset <span class="Constant">") "</span> xreg <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> divide *var2/reg2 => <span class="Constant">"f3 0f 5e/divide *"</span> reg2 <span class="Constant">" "</span> xreg <span class="Constant">"/x32"</span> + +There are also some exclusively floating-point instructions: + +var/xreg <span class="SpecialChar"><-</span> reciprocal var2/xreg2 => <span class="Constant">"f3 0f 53/reciprocal 3/mod "</span> xreg2 <span class="Constant">"/xm32 "</span> xreg1 <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> reciprocal var2 => <span class="Constant">"f3 0f 53/reciprocal *(ebp+"</span> var2.stack-offset <span class="Constant">") "</span> xreg <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> reciprocal *var2/reg2 => <span class="Constant">"f3 0f 53/reciprocal *"</span> reg2 <span class="Constant">" "</span> xreg <span class="Constant">"/x32"</span> + +var/xreg <span class="SpecialChar"><-</span> square-root var2/xreg2 => <span class="Constant">"f3 0f 51/square-root 3/mod "</span> xreg2 <span class="Constant">"/xm32 "</span> xreg1 <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> square-root var2 => <span class="Constant">"f3 0f 51/square-root *(ebp+"</span> var2.stack-offset <span class="Constant">") "</span> xreg <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> square-root *var2/reg2 => <span class="Constant">"f3 0f 51/square-root *"</span> reg2 <span class="Constant">" "</span> xreg <span class="Constant">"/x32"</span> + +var/xreg <span class="SpecialChar"><-</span> inverse-square-root var2/xreg2 => <span class="Constant">"f3 0f 52/inverse-square-root 3/mod "</span> xreg2 <span class="Constant">"/xm32 "</span> xreg1 <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> inverse-square-root var2 => <span class="Constant">"f3 0f 52/inverse-square-root *(ebp+"</span> var2.stack-offset <span class="Constant">") "</span> xreg <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> inverse-square-root *var2/reg2 => <span class="Constant">"f3 0f 52/inverse-square-root *"</span> reg2 <span class="Constant">" "</span> xreg <span class="Constant">"/x32"</span> + +var/xreg <span class="SpecialChar"><-</span> min var2/xreg2 => <span class="Constant">"f3 0f 5d/min 3/mod "</span> xreg2 <span class="Constant">"/xm32 "</span> xreg1 <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> min var2 => <span class="Constant">"f3 0f 5d/min *(ebp+"</span> var2.stack-offset <span class="Constant">") "</span> xreg <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> min *var2/reg2 => <span class="Constant">"f3 0f 5d/min *"</span> reg2 <span class="Constant">" "</span> xreg <span class="Constant">"/x32"</span> + +var/xreg <span class="SpecialChar"><-</span> max var2/xreg2 => <span class="Constant">"f3 0f 5f/max 3/mod "</span> xreg2 <span class="Constant">"/xm32 "</span> xreg1 <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> max var2 => <span class="Constant">"f3 0f 5f/max *(ebp+"</span> var2.stack-offset <span class="Constant">") "</span> xreg <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> max *var2/reg2 => <span class="Constant">"f3 0f 5f/max *"</span> reg2 <span class="Constant">" "</span> xreg <span class="Constant">"/x32"</span> + +Remember, when these instructions use indirect mode, they still use an integer +register. Floating-point registers can't hold addresses. + +Most instructions operate exclusively on integer or floating-point operands. +The only exceptions are the instructions for converting between integers and +floating-point numbers. + +var/xreg <span class="SpecialChar"><-</span> convert var2/reg2 => <span class="Constant">"f3 0f 2a/convert-to-float %"</span> reg2 <span class="Constant">" "</span> xreg <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> convert var2 => <span class="Constant">"f3 0f 2a/convert-to-float *(ebp+"</span> var2.stack-offset <span class="Constant">") "</span> xreg <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> convert *var2/reg2 => <span class="Constant">"f3 0f 2a/convert-to-float *"</span> reg2 <span class="Constant">" "</span> xreg <span class="Constant">"/x32"</span> + +var/reg <span class="SpecialChar"><-</span> convert var2/xreg2 => <span class="Constant">"f3 0f 2d/convert-to-int 3/mod "</span> xreg2 <span class="Constant">"/xm32 "</span> reg <span class="Constant">"/r32"</span> +var/reg <span class="SpecialChar"><-</span> convert var2 => <span class="Constant">"f3 0f 2d/convert-to-int *(ebp+"</span> var2.stack-offset <span class="Constant">") "</span> reg <span class="Constant">"/r32"</span> +var/reg <span class="SpecialChar"><-</span> convert *var2/reg2 => <span class="Constant">"f3 0f 2d/convert-to-int *"</span> reg2 <span class="Constant">" "</span> reg <span class="Constant">"/r32"</span> + +There are no instructions accepting floating-point literals. To obtain integer +literals in floating-point registers, copy them to general-purpose registers +and then convert them to floating-point. + +One pattern you may have noticed above is that the floating-point instructions +above always write to registers. The only exceptions are `copy` instructions, +which can write to memory locations. + +var/xreg <span class="SpecialChar"><-</span> copy var2/xreg2 => <span class="Constant">"f3 0f 11/<- 3/mod "</span> xreg <span class="Constant">"/xm32 "</span> xreg2 <span class="Constant">"/x32"</span> +copy-to var1, var2/xreg => <span class="Constant">"f3 0f 11/<- *(ebp+"</span> var1.stack-offset <span class="Constant">") "</span> xreg <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> copy var2 => <span class="Constant">"f3 0f 10/-> *(ebp+"</span> var2.stack-offset <span class="Constant">") "</span> xreg <span class="Constant">"/x32"</span> +var/xreg <span class="SpecialChar"><-</span> copy *var2/reg2 => <span class="Constant">"f3 0f 10/-> *"</span> reg2 <span class="Constant">" "</span> xreg <span class="Constant">"/x32"</span> + +Comparisons must always start with a register: + +compare var1/xreg1, var2/xreg2 => <span class="Constant">"0f 2f/compare 3/mod "</span> xreg2 <span class="Constant">"/xm32 "</span> xreg1 <span class="Constant">"/x32"</span> +compare var1/xreg1, var2 => <span class="Constant">"0f 2f/compare 2/mod *(ebp+"</span> var2.stack-offset <span class="Constant">") "</span> xreg1 <span class="Constant">"/x32"</span> + vim:ft=mu:nowrap:textwidth=<span class="Constant">0</span> </pre> </body> |