Toggle search
Search
Toggle menu
notifications
Toggle personal menu
Editing
Spec.isa
(section)
From Turing Complete
Views
Read
Edit
Edit source
View history
associated-pages
Page
Discussion
More actions
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
=== Virtual operands === <pre> %bits = 0 - popcount(%c) </pre> In addition to the operands included in the instruction syntax, additional "virtual" operands can be created to simplify instruction creation or, as in this example, to provide some minimal compile-time correctness guarantees. The general syntax is: <pre> %name:size = expression </pre> <code>name</code> and <code>size</code> follow the same definition rules as [[#Instruction_Operands|instruction operands]]. <code>expression</code> is a relatively typical mathematical expression using C-like operators and a handful of built-in functions. ==== Expression Operators ==== The game provides a limited set of operators for the construction of virtual operands: {| class="wikitable" ! Operator !! Description !! Example !! Result if %a = -30000, 16-bit |- | <code>+</code> || addition || <code>%a + 7</code> || -29993 |- | <code>-</code> || subtraction || <code>%a - 7</code> || -20007 |- | <code>*</code> || multiplication || <code>%a * 7</code> || -13392 |- | <code>/</code> || division || <code>%a / 7</code> || -4285 |- | <code>%</code> || modulo (remainder after division) || <code>%a % 7</code> || -5 |- | <code>&</code> || bitwise AND || <code>%a & 7</code> || 0 |- | <code><nowiki>|</nowiki></code> || bitwise OR || <code>%a <nowiki>|</nowiki> 7</code> || -29993 |- | <code>^</code> || bitwise XOR || <code>%a ^ 7</code> || -29993 |- | <code><<</code> || logical shift left (LSL) || <code>%a << 7</code> || 26624 |- | <code>>></code> || logical shift right (LSR) || <code>%a >> 7</code> || 277 |} A notable omission is the lack of unary operators. However, the two most common unary operations can be written using binary operators as follows: {| class="wikitable" ! Operator !! Description !! Alternative |- | <code>~</code> || bitwise NOT || <code>(-1 ^ %a)</code> |- | <code>-</code> || negation || <code>(0 - %a)</code> |} {{note|type=warn|Be cautious of unexpected bit width extension when using signed values. The parser is fairly good at doing the right thing, but it can occasionally get confused and sign extend to a full 64 bits. When in doubt, [[#Addendum:_Masking|mask]] it out!}} ==== Operator precedence ==== The game only defines three precedence levels: {| class="wikitable" ! Precedence !! Operators |- | Parenthesis || <code>()</code> |- | Multiplicative || <code>*</code>, <code>/</code>, <code>%</code> |- | Everything else || <code>+</code>, <code>-</code>, <code>&</code>, <code><nowiki>|</nowiki></code>, <code>^</code>, <code><<</code>, <code>>></code> |} ==== Functions ==== The game also provides a handful of built-in functions for the construction of virtual operands: {| class="wikitable" ! Function !! Description !! Example !! Result if %a = -30000 and %b = 27, 16-bit |- | <code>asr</code> || arithmetic shift right (ASR) || <code>asr(%a, 7)</code> || -235 |- | <code>log2</code> || floor of the base-2 logarithm if >0, -1 otherwise || <code>log2(%a)</code> <br> <code>log2(%b)</code> || -1 <br> 4 |- | <code>popcount</code> || number of <code>1</code>s in the base-2 representation || <code>popcount(%a)</code> || 6 ({{note}} Currently reports 54 as of 0.1354. [[#Addendum:_Masking|mask]] out high bits as needed for <64bit values.) |- | <code>trailing_zeros</code> || number of <code>0</code>s after the rightmost <code>1</code> in the base-2 representation || <code>trailing_zeros(%a)</code> || 4 |} ==== Instruction Address ==== The special character <code>$</code> returns the memory address of the start of the current instruction. This is useful for instructions such as relative jumps. If we assume <code>0b01000000</code> is the opcode for an absolute unconditional jump, we can use the following example to create a relative jump instruction without any additional hardware: <pre> jmp_rel %offset:S16(immediate) %target = $ + %offset 01000000 tttttttt tttttttt </pre> {{note|type=info|This instruction only will only work with immediate values. If you try to use a register, you would get the register index - not its contents - added to the instruction address.}} ==== Bit slicing ==== The expression evaluator also provides syntax for picking specific bits from a value, known as "slicing". This is written as <code>value[start:end]</code> where all three parts (<code>value</code>, <code>start</code>, and <code>end</code>) can be arbitrary expressions. <code>start</code> and <code>end</code> are inclusive indices into the bits of value, with the LSB being 0 and numbering being right-to-left. To make this a bit simpler to visualize, start has to be larger than end. For example, the slice <code>%imm[5:2]</code> applied to the value 90 (<code>0b01011010</code>) would result in 6 (<code>0b0110</code>), as shown: <pre> 76543210 |||| vvvv 0b01011010 </pre> ==== Expression Operands ==== Operations in the expression can refer to any operands from the instruction definition, as well as any virtual operands created on the preceding lines. {{note|type=warn|As alluded to in the [[#Instruction_Address|instruction address]] <code>rel_jmp</code> example, expressions are computed at assembly time. You cannot utilize runtime values such as register or memory contents - you'll get the index or address instead of the value. Runtime calculations can only be done by your hardware components.}} ==== Bit widths ==== Some operations (such as multiplication) will easily allow you to exceed the bit width of the virtual operand you're creating, or of the final output bytes. The game will cause an error when that occurs. Additionally, negative values are prone to being interpreted as 64-bit unsigned values (as of 0.1354 Beta) which can cause unexpected errors and odd-looking error messages. When in doubt, [[#Addendum:_Masking|mask]] out the result of your expressions to ensure they fit within the intended bit width, especially when working with signed values.
Summary:
Please note that all contributions to Turing Complete are considered to be released under the Creative Commons Attribution-ShareAlike (see
TuringComplete:Copyrights
for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)