New vCPU instructions 2.0

Using, learning, programming and modding the Gigatron and anything related.
Forum rules
Be nice. No drama.
lb3361
Posts: 52
Joined: 17 Feb 2021, 23:07

Re: New vCPU instructions 2.0

Post by lb3361 »

I have about 10% reduction in code size, but I am only using a subset of the new instructions as I do not know their opcodes and I cannot test.

I also read you have a number of interesting sys calls. I am hoping to use as many of them as possible, then maybe propose new ones. For instance, memcpy() https://github.com/lb3361/gigatron-lcc/ ... c/memcpy.s is ready for using a SYS_CopyMemory that resembles the SYS_SetMemory that memset() already uses. See also _memscan.s in the same subdir. I am also planning a SYS_CopyMemoryExt that writes into another memory bank, something that is very hard to do with the vCPU alone.

Note that I distinguish libc from the runtime support routines that implement mul, div, shifts, long int support, float support. Those are in https://github.com/lb3361/gigatron-lcc/ ... on/runtime. The rely on the traditional stack with push and pop. They use 0x81-0x88 for the accumulator LAC or FAC. They temporarily can 0x88-0x8F and sysFn/sysArgs, but do not rely on them being preserved between calls. I am doing it this way to augment the chances of sharing code for all this. This is almost complete and passes a test suite. I just need one or two nights of insomnia to finish the fp support.
at67
Posts: 332
Joined: 14 May 2018, 08:29

Re: New vCPU instructions 2.0

Post by at67 »

My bad, I completely forgot about the opcodes, here's the current list:

Code: Select all

_asmOpcodes["LDWI"  ] = {0x11, 0x00, ThreeBytes, vCpu};
_asmOpcodes["DEC"   ] = {0x14, 0x00, TwoBytes,   vCpu};
_asmOpcodes["MOVQ"  ] = {0x16, 0x00, ThreeBytes, vCpu};
_asmOpcodes["LSRB"  ] = {0x18, 0x00, TwoBytes,   vCpu};
_asmOpcodes["LD"    ] = {0x1A, 0x00, TwoBytes,   vCpu};
_asmOpcodes["SEXT"  ] = {0x1C, 0x00, TwoBytes,   vCpu};
_asmOpcodes["CMPHS" ] = {0x1F, 0x00, TwoBytes,   vCpu};
_asmOpcodes["LDW"   ] = {0x21, 0x00, TwoBytes,   vCpu};
_asmOpcodes["PEEK+" ] = {0x23, 0x00, TwoBytes,   vCpu};
_asmOpcodes["POKEI" ] = {0x25, 0x00, TwoBytes,   vCpu};
_asmOpcodes["LSLV"  ] = {0x27, 0x00, TwoBytes,   vCpu};
_asmOpcodes["ADDBA" ] = {0x29, 0x00, TwoBytes,   vCpu};
_asmOpcodes["STW"   ] = {0x2B, 0x00, TwoBytes,   vCpu};
_asmOpcodes["ADDBI" ] = {0x2D, 0x00, ThreeBytes, vCpu};
_asmOpcodes["DBNE"  ] = {0x32, 0x00, ThreeBytes, vCpu};
_asmOpcodes["DOKEI" ] = {0x37, 0x00, ThreeBytes, vCpu};
_asmOpcodes["PEEKV" ] = {0x39, 0x00, TwoBytes,   vCpu};
_asmOpcodes["DEEKV" ] = {0x3B, 0x00, TwoBytes,   vCpu};
_asmOpcodes["XORBI" ] = {0x3D, 0x00, ThreeBytes, vCpu};
_asmOpcodes["ANDBA" ] = {0x42, 0x00, TwoBytes,   vCpu};
_asmOpcodes["ORBA"  ] = {0x44, 0x00, TwoBytes,   vCpu};
_asmOpcodes["XORBA" ] = {0x46, 0x00, TwoBytes,   vCpu};
_asmOpcodes["NOTB"  ] = {0x48, 0x00, TwoBytes,   vCpu};
_asmOpcodes["DOKE+" ] = {0x4A, 0x00, TwoBytes,   vCpu};
_asmOpcodes["LDI"   ] = {0x59, 0x00, TwoBytes,   vCpu};
_asmOpcodes["MOVQW" ] = {0x5B, 0x00, ThreeBytes, vCpu};
_asmOpcodes["ST"    ] = {0x5E, 0x00, TwoBytes,   vCpu};
_asmOpcodes["DEEK+" ] = {0x60, 0x00, TwoBytes,   vCpu};
_asmOpcodes["POP"   ] = {0x63, 0x00, OneByte,    vCpu};
_asmOpcodes["MOV"   ] = {0x65, 0x00, ThreeBytes, vCpu};
_asmOpcodes["PEEKA" ] = {0x67, 0x00, TwoBytes,   vCpu};
_asmOpcodes["POKEA" ] = {0x69, 0x00, TwoBytes,   vCpu};
_asmOpcodes["TEQ"   ] = {0x6B, 0x00, TwoBytes,   vCpu};
_asmOpcodes["TNE"   ] = {0x6D, 0x00, TwoBytes,   vCpu};
_asmOpcodes["DEEKA" ] = {0x6F, 0x00, TwoBytes,   vCpu};
_asmOpcodes["PUSH"  ] = {0x75, 0x00, OneByte,    vCpu};
_asmOpcodes["SUBBA" ] = {0x77, 0x00, TwoBytes,   vCpu};
_asmOpcodes["INCW"  ] = {0x79, 0x00, TwoBytes,   vCpu};
_asmOpcodes["DECW"  ] = {0x7B, 0x00, TwoBytes,   vCpu};
_asmOpcodes["DOKEA" ] = {0x7D, 0x00, TwoBytes,   vCpu};
_asmOpcodes["LUP"   ] = {0x7F, 0x00, TwoBytes,   vCpu};
_asmOpcodes["ANDI"  ] = {0x82, 0x00, TwoBytes,   vCpu};
_asmOpcodes["CALLI" ] = {0x85, 0x00, ThreeBytes, vCpu};
_asmOpcodes["ORI"   ] = {0x88, 0x00, TwoBytes,   vCpu};
_asmOpcodes["NOTW"  ] = {0x8A, 0x00, TwoBytes,   vCpu};
_asmOpcodes["XORI"  ] = {0x8C, 0x00, TwoBytes,   vCpu};
_asmOpcodes["DBGE"  ] = {0x8E, 0x00, ThreeBytes, vCpu};
_asmOpcodes["BRA"   ] = {0x90, 0x00, TwoBytes,   vCpu};
_asmOpcodes["INC"   ] = {0x93, 0x00, TwoBytes,   vCpu};
_asmOpcodes["ORBI"  ] = {0x95, 0x00, ThreeBytes, vCpu};
_asmOpcodes["CMPHU" ] = {0x97, 0x00, TwoBytes,   vCpu};
_asmOpcodes["ADDW"  ] = {0x99, 0x00, TwoBytes,   vCpu};
_asmOpcodes["LDNI"  ] = {0x9C, 0x00, TwoBytes,   vCpu};
_asmOpcodes["ANDBK" ] = {0x9E, 0x00, ThreeBytes, vCpu};
_asmOpcodes["ORBK"  ] = {0xA0, 0x00, ThreeBytes, vCpu};
_asmOpcodes["XORBK" ] = {0xA2, 0x00, ThreeBytes, vCpu};
_asmOpcodes["PEEKA+"] = {0xA4, 0x00, TwoBytes,   vCpu};
_asmOpcodes["CMPI"  ] = {0xA7, 0x00, ThreeBytes, vCpu};
_asmOpcodes["PEEK"  ] = {0xAD, 0x00, OneByte,    vCpu};
_asmOpcodes["SYS"   ] = {0xB4, 0x00, TwoBytes,   vCpu};
_asmOpcodes["SUBW"  ] = {0xB8, 0x00, TwoBytes,   vCpu};
_asmOpcodes["JEQ"   ] = {0xBB, 0x00, ThreeBytes, vCpu};
_asmOpcodes["JNE"   ] = {0xBD, 0x00, ThreeBytes, vCpu};
_asmOpcodes["JLT"   ] = {0xBF, 0x00, ThreeBytes, vCpu};
_asmOpcodes["JGT"   ] = {0xC1, 0x00, ThreeBytes, vCpu};
_asmOpcodes["JLE"   ] = {0xC3, 0x00, ThreeBytes, vCpu};
_asmOpcodes["JGE"   ] = {0xC5, 0x00, ThreeBytes, vCpu};
_asmOpcodes["DEF"   ] = {0xCD, 0x00, TwoBytes,   vCpu};
_asmOpcodes["CALL"  ] = {0xCF, 0x00, TwoBytes,   vCpu};
_asmOpcodes["POKE+" ] = {0xD1, 0x00, TwoBytes,   vCpu};
_asmOpcodes["NEGW"  ] = {0xD3, 0x00, TwoBytes,   vCpu};
_asmOpcodes["TGE"   ] = {0xD5, 0x00, TwoBytes,   vCpu};
_asmOpcodes["TLT"   ] = {0xD7, 0x00, TwoBytes,   vCpu};
_asmOpcodes["TGT"   ] = {0xD9, 0x00, TwoBytes,   vCpu};
_asmOpcodes["TLE"   ] = {0xDB, 0x00, TwoBytes,   vCpu};
_asmOpcodes["ANDBI" ] = {0xDD, 0x00, ThreeBytes, vCpu};
_asmOpcodes["ALLOC" ] = {0xDF, 0x00, TwoBytes,   vCpu};
_asmOpcodes["SUBBI" ] = {0xE1, 0x00, ThreeBytes, vCpu};
_asmOpcodes["ADDI"  ] = {0xE3, 0x00, TwoBytes,   vCpu};
_asmOpcodes["SUBI"  ] = {0xE6, 0x00, TwoBytes,   vCpu};
_asmOpcodes["LSLW"  ] = {0xE9, 0x00, OneByte,    vCpu};
_asmOpcodes["STLW"  ] = {0xEC, 0x00, TwoBytes,   vCpu};
_asmOpcodes["LDLW"  ] = {0xEE, 0x00, TwoBytes,   vCpu};
_asmOpcodes["POKE"  ] = {0xF0, 0x00, TwoBytes,   vCpu};
_asmOpcodes["DOKE"  ] = {0xF3, 0x00, TwoBytes,   vCpu};
_asmOpcodes["DEEK"  ] = {0xF6, 0x00, OneByte,    vCpu};
_asmOpcodes["ANDW"  ] = {0xF8, 0x00, TwoBytes,   vCpu};
_asmOpcodes["ORW"   ] = {0xFA, 0x00, TwoBytes,   vCpu};
_asmOpcodes["XORW"  ] = {0xFC, 0x00, TwoBytes,   vCpu};
_asmOpcodes["RET"   ] = {0xFF, 0x00, OneByte,    vCpu};

// Psuedo vCPU instructions
_asmOpcodes["HALT"  ] = {0xB4, 0x80, TwoBytes,   vCpu};

// PREFX3 vCPU instructions
_asmOpcodes["ST2"   ] = {0xC7, 0x11, FourBytes, vCpu};
_asmOpcodes["STW2"  ] = {0xC7, 0x14, FourBytes, vCpu};
_asmOpcodes["XCHG"  ] = {0xC7, 0x17, FourBytes, vCpu};
_asmOpcodes["MOVW"  ] = {0xC7, 0x19, FourBytes, vCpu};
_asmOpcodes["ADDWI" ] = {0xC7, 0x1B, FourBytes, vCpu};
_asmOpcodes["SUBWI" ] = {0xC7, 0x1D, FourBytes, vCpu};
_asmOpcodes["ANDWI" ] = {0xC7, 0x1F, FourBytes, vCpu};
_asmOpcodes["ORWI"  ] = {0xC7, 0x21, FourBytes, vCpu};
_asmOpcodes["XORWI" ] = {0xC7, 0x23, FourBytes, vCpu};
_asmOpcodes["LDPX"  ] = {0xC7, 0x25, FourBytes, vCpu};
_asmOpcodes["STPX"  ] = {0xC7, 0x28, FourBytes, vCpu};
_asmOpcodes["CONDI" ] = {0xC7, 0x2B, FourBytes, vCpu};
_asmOpcodes["CONDB" ] = {0xC7, 0x2D, FourBytes, vCpu};
_asmOpcodes["CONDIB"] = {0xC7, 0x30, FourBytes, vCpu};
_asmOpcodes["CONDBI"] = {0xC7, 0x33, FourBytes, vCpu};

// Gigatron vCPU branch instructions
_asmOpcodes["BEQ"] = {0x35, 0x3F, ThreeBytes, vCpu};
_asmOpcodes["BGT"] = {0x35, 0x4D, ThreeBytes, vCpu};
_asmOpcodes["BLT"] = {0x35, 0x50, ThreeBytes, vCpu};
_asmOpcodes["BGE"] = {0x35, 0x53, ThreeBytes, vCpu};
_asmOpcodes["BLE"] = {0x35, 0x56, ThreeBytes, vCpu};
_asmOpcodes["BNE"] = {0x35, 0x72, ThreeBytes, vCpu};
I'll post more information on the Sys calls tonight.
lb3361
Posts: 52
Joined: 17 Feb 2021, 23:07

Re: New vCPU instructions 2.0

Post by lb3361 »

I also need to know the order of the operands. For instance, ORBI(x,y) is x the address aa and y the immediate II? Which one comes first in the encoding: 95 aa ii or 95 ii aa? Plus I need to test. This is why I prefer to wait for the rom source.
lb3361
Posts: 52
Joined: 17 Feb 2021, 23:07

Re: New vCPU instructions 2.0

Post by lb3361 »

Ideas for prefix2.

I now have long and fp support in the C compiler. One of the issues is that code becomes very bulky because moving data around requires a lot of instructions. For instance moving a long between registers requires 2 ldw and 2 stw (8 bytes) and moving a float requires another 4 bytes for the exponent. Replacing these instructions by a little routine is not much of a saving because preparing the arguments (src and dst address) still makes for bulky call sequences. This bulky code means that routines do not easily fit in the 96 bytes that follow a scanline, which causes another layer of slowdowns.

So, before even thinking of supporting long and float arithmetic with SYS calls, it would be desirable to have MOVL v1,v2 (moving 4 bytes) and MOVF v1,v2 (moving 5 bytes), and maybe even LOKEA/LEEKA and fp equivalents (FOKEA might not be a good name.) Doing this might involve writing instructions that self restart like SYS. This might seem slow, but the code size benefits are substantial enough.

I am therfore eager to see your rom to propose such prefix2 instructions.


- L.
Post Reply