Close

Aliases

A project log for Assembly Language for ECM-16/TTL homebrew CPU

Sub-project where the assembly language is described; the assembler program progress updates are posted here

pavelPavel 11/23/2022 at 06:310 Comments

Aliases are additional mnemonics for pseudo-instructions, which are substituted by assembler with proper instruction mnemonics right before translating to machine code.

For now, this is a "TO DO" list, to be implemented in assembler.

There are several groups of aliases:


Prefixes:

these are modifiers for MOV and LD/ST (LDr/STr) instructions that change the size of data transferred, this way it is easier to use/understand them.

Here is translation to proper instruction:

2W  = SETPR 0     -- Move, Load or Store 2 words into 2 adjacent registers (aligned to even, e.g. r0 and r1, or r6 and r7)

4W = SETPR 1       -- Move, Load or Store 4 words into 4 adjacent registers (aligned by 4, e.g. to r4, r5, r6 and r7)

8W = SETPR 2     -- Move, Load or Store 8 words into  8 adjacent registers (either all GPR or all MemPointer registers at once)

16W = SETPR 3     -- Move, Load or Store 16 words into all 16 registers, first 8 words into GPR and last 8 words into MemPointers

1B = SETPR 4        -- Load or Store 1 byte into 1 register

2B = SETPR 5       -- Load or Store 2 bytes into 2 adjacent registers (aligned to even, e.g. r0 and r1, or r6 and r7)

4B = SETPR 6       -- Load or Store 4 bytes into 4 adjacent registers (aligned by 4, e.g. to r4, r5, r6 and r7)

8B = SETPR 7       -- Load or Store 8 bytes into 8 adjacent registers (either all GPR or all MemPointer registers at once)

Byte loads and stores use least significant half of word/register. 

Byte prefixes are used only for memory accesses, MOV instructions always transfer whole words (full register content)

Examples of prefix uses:

4W MOV r4 r0  -- copy registers in range r0..r3 into range r4..r7

2W LD SPH BP -- load Stack Pointer pair (SPH and SPL) with value at address stored in Base Pointer pair.

1B STob r0 SP -1 -- push one byte from register r0 to stack


Multi-word ALU operations

Provision for loading/storing and moving multiple words per instruction is complemented by extensions of ALU operations -- these just combinations of regular ALU ops that result in effective operations on data with widths bigger than 16 bit.

Following instructions can have 2-word and 4-word versions:

ADD, SUB, ADDC, SUBC, AND, ANDN, OR, ORN, XOR, XNOR, SHR, SHL, ASHR, ASHL, ROLC, RORC.

The versions are distinguished by additional letter added at the end, 'd' for operations on 32-bit values (double-word), 'l' for operations on 64-bit values (long, or quad-word).

Example:

ADDl r0 r0 r4

this is substituted with:

ADD r3 r3 r7
ADDC r2 r2 r6
ADDC r1 r1 r5
ADDC r0 r0 r4

 by the Assembler.

Use of these instructions make registers appear longer, while their number drops accordingly: instead 8 16-bit registers, it looks like 4 32-bit or 2 64-bit registers.


Jump to absolute address

Regular jumps are PC-relative.

This alias makes possible jumps to absolute address in ranges 0x0000_0000 -- 0x00FF_FFFF and 0xFF00_0000 -- 0xFFFF_FFFF.

This is just an immediate load of 25-bit value into Memory Pointer Pair:

JA address == LDim PC address


Shorthand for PC-relative loads and stores

This is for loading and storing to labeled locations (static variables).

As labels (for variables) are mapped to addresses with respect to program origin, but the program itself may be loaded anywhere in memory, it is handy to provide pc-relative way to access them. This way, the offset is calculated by the assembler. Thus there is no need to have PC as part of instructions.

Here are relevant aliases:

LDo rX Label == LDo rX PC <Label - PC - 2>

STo rX Label == STo rX PC <Label - PC - 2>

The <Label - PC - 2> is calculated offset from current PC value to labeled value.


Stack operations (push and pop)

These are pre-defined loads and stores with update to the SP:

Push and pop of single register (either rX or mpX):

PUSH rX == STob rX SP -2   --- decrement SP by 2, and store value in reg rX at new address

POP rX == LDoa rX SP +2   --- load reg rX with value at address in SP, and then increment SP by 2

PUSH MP == SETPR 0;  STob MPH SP -4   --- decrement SP by 4, and store value in registers MPH and MPL at new address

POP MP == SETPR 0; LDoa MPH SP +4   --- load registers MPH and MPL with value at address in SP, and then increment SP by 4

PUSH RF == SETPR 2; STob r0 SP -16   --- decrement SP by 16, and store entire Register File at new address

POP RF == SETPR 2; LDoa r0 SP +16   --- load whole Register File at once with value at address in SP, and then increment SP by 16

Discussions