Some ideas for a 64-bit PDP10-compatible CPU -- the PDP-100 ----------------------------------------------------------- Instruction and pointer formats ------------------------------- +-+----------------+---------+----+-+----+--------------+------------------+ |0| N/A | OP | AC |I| | N/A | | +-+----------+-+-+-+---------+----+-+ X +--------------+ Y | |1| OP |N|I|L| AC | | | +-+----------+-+-+-+---------+-----------+---------------------------------+ 0 1234567012 3 4 5 670123456 7012 3 4567 01234567012345 670123456701234567 0 1 2 3 4 5 6 7 Byte pointers have POS in the AC field and SIZ in the OP field. If N is set, the Y field extends to include the X field. (36-bit byte pointers use traditional format.) All ops specified as: C(AC) := C(R) op C(E) This also applies to temporaries, e.g. ILDB, etc Two-operand mode is always indexed (even w/ 0). New assembler syntax for three-argument opcodes, e.g.: ADDI AC,R,E ADDI AC,E generates ADDI AC,AC,E, not ADDI AC,E(0) New assembler syntax for fullword addressing, e.g: MOVE AC,@*E ; fullword MOVE AC,*E(IX) ; fullword indexed The PC is 41. bits only (w/ room for flags in LH); attempts to jump to larger addresses will trap. Instructions are a superset of KS-10. (Additional bit is always 0 in compatibility mode) Not compatible with KL extended addresses or double moves. Effective address decoding -------------------------- IFETCH: MA := PC If bit 00 of C(MA) == 0 then: ; PDP-10 compatibility mode OP := Bits 16:26 of C(MA) R := AC := Bits 27:32 of C(MA) EAC10: I := Bit 33 of C(MA) X := Bits 34:37 of C(MA) E := Bits 56:77 of C(MA) If X <> 0 then: ; Compatible indexed E := Bits 56:77 of E+C(X) If I == 1 then: ; Compatible indirect MA := E Go to EAC10 DONE OP := Bits 01:12 of C(MA) AC := Bits 16:22 of C(MA) N := Bit 13 of C(MA) If N == 0 then: ; Traditional two-operand mode R := AC Else: ; New three-operand mode R := Bits 27:37 of C(MA) F := 0 EACOMP: If Bit 00 of C(MA) == 0: ; Compatible pointer Go to EAC10 N := Bit 13 of C(MA) I := Bit 14 of C(MA) L := Bit 15 of C(MA) If L == 0 or N == 0 or F == 0 then: ; Halfword address E := Bits 40:77 of C(MA) Else: ; Long address E := Bits 27:77 of C(MA) If N == 0 then: ; Use index register X := Bits 27:37 of C(MA) If L == 0 then: ; Truncated indexed E := Bits 40:77 of E+C(X) Else: ; Fullword indexed E := E + C(X) If I == 1 then: ; Indirect MA := E If L == 0 then: ; Traditional recursive F := 1 Go to EACOMP Else: ; Fullword address E := C(MA) DONE Ref: http://www.inwap.com/pdp10/opcodes.html Instructions 2000-2777 are about the same as PDP-10 000-777; 3000-3777 are new, mostly orthogonalizations. 2000-2077, 3000-3077: Additional bit available for UUOs Instrs canonicalized after effective address computation, N = I = L = 1, X = R, Y = [next word] Full effective address in next word 2100-2177, 3100-3177: Floating point - use 64-bit IEEE, don't try to be bug compatible Double-extended precision (128 bits) in 3100-3177 SQRT/DSQRT -- new DBP/DLDB/DDPB -- decrement byte pointer (in 3100-3177) 2200-2277, 3200-3277: DMOV - double word moves in 3200-3277 DADD/DSUB/DMUL/DDIV - double precision in 3200-3277 ASHC/ROTC/LSHC - obsoleted by DASH/DROT/DLSH in 3200-3277 ASHM/ROTM/LSHM/DASHM/DROTM/DLSHM - new shift ops, AC bits is shift amount, shifts data in C(E) DBLT - fullword address block transfer C(AC) is DST start C(AC+1) is SRC start C(E) is DST end New instrs BLS/DBLS - BLock Set As BLT/DBLT, except SRC is used immediate (and not incremented) instead of addressing memory New instrs BLX/DBLX - BLock eXecute As BLS/DBLS, except AC is XCT'd instead of used as data DXCT - double execute to bootstrap from the PDP10 instruction set, which cannot write into bits 00:33, use new instruction (in 2200-2277) to execute C(E),,C(E+1) as a fullword instruction 2300-2377, 3300-3377, 3400-3477, 3500-3577: SOS/AOS/SOJ/AOJ/SKIP/JUMP/CA* - two more bits, specifying (whole word, both halves, left half, right half) This makes old AOBJ* incompatibly obsolete. Half word SKIP/JUMP spelled SKPL, JMPR, etc 2400-2477: Logicals - Unchanged 2500-2577: Halfwords - unchanged 2600-2677, 3600-3677: Test instructions - add tests: T*N Not equal any bits set (old) T*E Equal no bits set (old) T*S all Set non-zero mask and all bits set T*Z Zeroes any bits clear T*O Ones only no bits clear T*C all Clear non-zero mask and all bits clear 2700-2777: All I/O ops use generic instruction format. 3700-3777: Maybe use new bits for something else ?? ---------------------------------------------------------------------- From Lars Brinkhoff: (Certainly, not all of these would be a good idea.) Byte instructions: LDBE Retrieve a byte of S bits from the location and position specified by the pointer at location E, load it into the right end of AC, and make all the remaining bits equal to the most significant bit of the byte. ILDBE Increment the byte pointer at location E, setting the byte alignment to zero if the incrementing crosses a word boundary. Then retrieve a byte of S bits from the location and position specified by the pointer at location E, load it into the right end of AC, and make all the remaining bits equal to the most significant bit of the byte. LDBI, LDBEI, DPBI Like the corresponding pre-incrementing instructions, but the incrementation occurs after the byte has been retrieved. SUBBP Subtract the byte pointer at location E from the byte pointer in AC, and store the result in AC. The S fields of the pointers must be equal, or else. CMPBPm If the byte pointer in E compares to the byte pointer in AC as specified by mode m (like in JUMP etc), skip the next instruction. Arithmetic instructions: SEXT Make bits 0 to 36-E in AC equal to bit E in AC. FFS If the location at E contains zero, clear AC. Otherwise, count the number of tailing 0s in it (the number of 0s to the right of the rightmost 1), and place that count plus 1 in AC. 72-bit addition and subtraction Like DADD and DSUB, except with a full 72-bit result (including sign bit). 72-bit multiplication Like MUL and/or DMUL, except with a full 72-bit result (including sign bit). 72-bit division Like DIV and/or DDIV, except with a full 72-bit result (including sign bit). MIN Equivalent to CAMLE AC,E MOVE AC,E MAX Equivalent to CAMGE AC,E MOVE AC,E Support for unsigned integers: UMULI Like MULI, but performs unsigned multiplication instead. Equivalent to MUL AC,E LSH AC+1,1 LSHC AC,43 except AC+1 shouldn't be modified by the instruction. UDIVI Like DIVI, but performs unsigned division instead. UJUMP Like JUMP, except the comparison is unsigned. Equivalent to TLC AC,400000 JUMP AC,E except AC shouldn't be modified by the instruction. USKIP Like SKIP, except the comparison is unsigned. UCAI Like CAI, except the comparison is unsigned. UCAM Like CAM, except the comparison is unsigned. UMIN Equivalent to UCAMLE AC,E MOVE AC,E UMAX Equivalent to UCAMGE AC,E MOVE AC,E Fast stack instructions for use with a global stack pointer only. XPUSH XPUSHJ XPOP XPOPJ The only difference from the standard stack instructions is that these don't have to make a slow test to find out if the stack pointer is in local or global format. Floating-point instructions: SQRT Store the square root of the single-precision floating-point number in the location at E in AC. DSQRT Store the square root of the double-precision floating-point number in the location at E,E+1 in AC,AC+1. GSQRT Store the square root of the giant-precision floating-point number in the location at E,E+1 in AC,AC+1. DFIX Convert the double-precision floating-point number in E,E+1 to a single-precision integer in AC. DFIXR Convert the double-precision floating-point number in E,E+1 by rounding to a single-precision integer in AC. ?FIX - need to come up with a name Convert the single-precision floating-point number in E to a double-precision integer in AC,AC+1. ?FIXR - need to come up with a name Convert the single-precision floating-point number in E by rounding to a double-precision integer in AC,AC+1. DDFIX Convert the double-precision floating-point number in E,E+1 to a double-precision integer in AC,AC+1. DDFIXR Convert the double-precision floating-point number in E,E+1 by rounding to a double-precision integer in AC,AC+1. DFLTR Convert the single-precision integer in E to a double-precision floating-point number in AC,AC+1. ?FLTR - need to come up with a name Convert the double-precision integer in E,E+1 to a single- precision floating-point number in AC. DDFLTR Convert the double-precision integer in E,E+1 to a double- precision floating-point number in AC,AC+1. DFSC Add the scale factor given by E to the exponent part of AC (thus multiplying AC,AC+1 by 2^E), normalize the resulting double-precision floating-point number bringing 0s into bit positions vacated at the right, and place the result back in AC,AC+1. DFSC would be equivalent to this two-instruction sequence: DFAD AC,[EXP 0,0] ; Make sure AC,AC+1 is normalized. FSC AC,E ; Now safe to perform scaling. ----------------------------------------------------------------------