On the 6000 series, the important thing that many programmers just learning the machine architecture miss (and this also applies to the Cray I) is that arithmetic is performed to 48 bit precision, in spite of the word being 60 bits long. The only exceptions that can deliver a 60 bit result are integer add and subtract. THe 64-bit STAR even carried this over to all arithmetic operations--48 bits, with the upper 16 bits serving other purposes.

Everything else is done in the floating point units. Both normalized and unnormalized (and rounded) operations are provided. Double-precision requires separate steps to form upper and lower results, where the lower result carries an exponent 48 less than the upper result.

This is very handy--to perform an integer multiply, one need only do a unnormalized double-precision (lower product) multiply. If the exponents of the operands are 0 and the operands are unnormalized, the result is the unnormalized product with a zero exponent, unless overflow has resulted, in which case the exponent will be nonzero. (Actually, when I say "zero" I mean zero biased by octal 2000.). The so-called "integer multiply" option merely forced the exponents of the operands to zero.

There is no detection of overflow for simple 60 bit integer addition or subtraction.

The use of separate instructions to recover upper and lower results was advantageous, given that there are __two__ multiply units, so that both halves of a double-precision product can be calculated with only a 1 minor cycle delay between them.

Recall that the Cray 1 didn't even have a divide instruction, but rather a "floating reciprocal approximation" instruction. A precise quotient could be computed with a couple of iterations of Newton's method from the product of the reciprocal and the dividend.

As regards instruction length, all register-register instructions on the 6000 are 15 bits in length--and are three-address. So an instruction could be issued every minor cycle, with delays only if an operand wasn't available. The issue logic could even "shortstop" a result by making it available for an instruction a minor cycle before it was realized in the register file.

Writing fast, efficient code for the 6600 was a great mental exercise.

Oh, and condition-code-less instruction sets should probably include PA-RISC.

=======================

Regarding the "skip" over two-word instructions. Certainly the 1130 skip (BSC) instruction would skip only one word, even if the following instruction was a two word one. One could use this as a programming "trick" by encoding a valid instruction as the second word (operand) of a two-word instruction. Could be confusing as heck to someone reading the code.

When CDC introduced the Compare-Move unit on the lower CYBER 70 (72/73) (corresponding to the 6400 and 6500) line, it wasn't available for the 74 (6600 architecture). So how to tell and make use of the thing? Well, a 15-bit no-op was octal 46000, and the CMU codes were shoehorned into this by making them 30 bit and 60 bit instructions, but starting with 46yxx, with "y" being nonzero. Since a CMU instruction had to occupy the first 30 bits of a word, coding one with a 30 bit jump in the lower 30 bits would result in a non-CMU machine executing a couple of no-ops and then the jump, while the CMU machine would see the word as a valid CMU instruction and consider the jump in the lower 30 bits part of the operands. It worked well on the entire range of 6000-7000 systems until the CYBER 170 series came out. It was never explained to me satisfactorily, but a no-op on a non-CMU CYBER 170 **had** to be coded as 46000--anything else threw an illegal instruction exception.

So, a variation on the theme...