11

In the BESM-6, there is an instruction (045) to add index registers, but not to subtract them, however, there is a nearby unused opcode 047, which is made synonymous to 045 (in fairness, that's true only in the kernel mode; in the user mode it traps as illegal).

Also, there are "branch if index is zero" (34) and "branch if index is not zero" (35), but not "branch if index is less than zero" (alternatively formulated as "branch if the MSB of the index is set"). However, there is a nearby unused opcode 36 which is made completely synonymous to 34.

This makes one to think that the unimplemented functionality was intended by the initial design (no references to confirm or deny it, unfortunately), but didn't make it into the hardware for one reason or another, be it physical space constraints, timing requirements, etc.

Are there any similar Western examples of an instruction set with obviously cut corners, or is this kind of mishap specific to socialist economy?

An answer could be in the form "Here's the instruction set of CPU X with an instruction with opcode A doing foo, but no instruction to do bar, which would be obvious to include for completeness/orthogonality; at the same time there is an unused opcode B close to A".

Leo B.
  • 19,082
  • 5
  • 49
  • 141
  • There are certainly a few cases where version one of a processor had issues that created unusable instructions, causing them not to be documented — if you'd bought an early 6502 and scanned its documentation you might have asked yourself 'why no ROR?'. But that was fixed quickly, and the faulty instructions weren't disabled. So not exactly the same thing. – Tommy Feb 01 '19 at 18:54
  • 10
    I'm tempted to vote for closing this, as answers can only be opinions. After all, as soon as a machine is Turing complete, it can produce any desired output, having more instructions just simplifies individual aspects. Most obvious with the branch example given, as both existing jumps can easy be used to synthesize the third. – Raffzahn Feb 01 '19 at 18:55
  • 3
    @Raffzahn No, not so easy. Try writing a "branch if negative" using only moves, additions, and branches if zero/non-zero in any architecture. – Leo B. Feb 01 '19 at 19:00
  • @Tommy "That was fixed quickly" is the key. – Leo B. Feb 01 '19 at 19:04
  • @Raffzahn I've updated the question. – Leo B. Feb 01 '19 at 19:11
  • 1
    @LeoB. Well, the first question would be about the index registers being signed values at all - are they? Not clear from the Page linked, so are they? If not, any test for negative doesn't make sense. – Raffzahn Feb 01 '19 at 19:22
  • 2
    @Raffzahn Given that the addition operation is 2's complement, a bit vector can be looked at as signed or unsigned arbitrarily. – Leo B. Feb 01 '19 at 19:28
  • @LeoB. That doesn't answer the issue. If at all it provides an alternative interpretation of the mechanics. If the designers thought of index registers as unsigned offset to be used in calculations, then a wraping at 2^14 is aside effect, not neccessary intention. Which again shows the very nature of this question is asking for unverifyable opinion. In fact, the changes made call even more for opinion - in form of instructions one would like to see, not if they were considered necessary at all. – Raffzahn Feb 01 '19 at 19:34
  • @Raffzahn OMG as if you never programmed for word-oriented architectures. For example, given a (smallish) number of bytes in R1, which might not be a multiple of bytes per word, starting in the word pointed to by R2, looping through them would be R1 -= bytes_per_word; ++R2. If R1 is 0, we're done; if R1 has a high bit set, we need to add bytes_per_word back and handle the partial word. – Leo B. Feb 01 '19 at 20:06
  • @LeoB. You are creating a very special situation and ask for a special instruction. cool, but that's your opinion. To do historic correct work it is to ask if this was intended at all. Or, as one could assume, that index registers where just that, an index - one that can as well address more than 16Ki units of data. Isn't it? But I think we really ended up now in a territory of opinion, nothing that is worth to be pursuit at all. – Raffzahn Feb 01 '19 at 20:25
  • You could easily argue "The Z80 amended all the instructions that were missing in the 8080" - But were they really missing? – tofro Feb 01 '19 at 20:29
  • PDP-8 has an instruction to add, but if you wanted to subtract you had to negate the accumulator then add. Does this count? But PDP-8 has a very limited instruction set, there's no place to put a subtract instruction. – Barmar Feb 01 '19 at 23:34
  • 1
    @Barmar No, if all opcodes were used, then the absence of the subtract instruction was by design rather than cutting corners at a later stage of production. – Leo B. Feb 01 '19 at 23:43
  • 1
    note that you only need a <= or < instruction to do any comparisons on ordered types. For example with <= we can do a == b, a > b, a < b as (a <= b) && (b <= a), not (a <= b) and not (b <= a) respectively. Having == and != is less useful. However as the BESM-6 has a shift instruction, I guess it'll be easy to do a "branch if negative". It also has other bitwise instructions like and, or, xor... which makes it a lot more useful than some educational architectures – phuclv Feb 07 '19 at 05:17
  • @phuclv My point is that the missing instruction would allow to reduce involving the ALU/FPU in address computations and comparisons. Doing a branch conditional on the accumulator value had to stop the pipeline; a branch conditional on the value of an index register proceeded in parallel with arithmetic operations. – Leo B. Feb 07 '19 at 05:39
  • 3
    The Data General Nova had Boolean AND but no Boolean OR. You could get around this with De Morgan's laws, but it seems like a fundamental instruction to omit. – Ken Shirriff Mar 12 '19 at 22:53
  • @KenShirriff Was it an omission by design, or was there a gaping hole in the opcode table? – Leo B. Mar 13 '19 at 16:19
  • 1
    I’m voting to close this question because it's really a list question. – Dranon Mar 24 '21 at 18:48
  • I'm tempted to vote-to-close since it is not clear what makes the non-existence of an instruction "blatant". – dave Oct 28 '23 at 23:38
  • @another-dave The question has been answered to my satisfaction (accepted). Why bother? – Leo B. Oct 29 '23 at 08:01
  • I looked at the question because it had bubbled to the 'recently changed' list. I paid no attention to its age, but answered anyway, as did others. I think the waters were muddied by your comment on the F8 answer, which was to try to distinguish 'deliberate' from 'blatant', FWIW, neither of the current VTCs is from me. – dave Oct 29 '23 at 13:05

6 Answers6

24

The 6502, released in 1975, had a missing instruction when first released: it had a ROL (ROtate bits Left) instruction, but no corresponding ROR (ROtate bits Right) instruction. This was reputed to have been because a bug was found in the circuit for the ROR instruction, but this has since been disproven by analysis of original 6502 dies: there's no evidence of the faulty/disabled instruction on the die; it was just never included.

While the ROR instruction was absent at first (as seen in the 1975 datasheet,page 6), it was soon added in a hardware revision, and the ROR instruction was included from the 1976 datasheet (page 5) onward.

Some versions of Microsoft BASIC for 6502 machines had workarounds in their floating point instructions to avoid using the ROR instruction. See https://www.pagetable.com/?p=45 for an example.

Kaz
  • 8,086
  • 2
  • 38
  • 81
  • Unlike 6502, the IC version of the BESM-6 CPU released more than a decade later, hasn't implemented the missing instructions, probably to avoid breaking code compatibility at the user level. – Leo B. Feb 05 '19 at 01:08
  • @OmarL Agreed, hence I described it as such in my answer. But you could argue that it was blatantly missing (from the programmer's point of view) in the initial release. – Kaz Mar 25 '21 at 13:46
  • 6
    The instructions INA and DEA were blatantly missing from the original 6502 IMO (and deliberately so). See also https://retrocomputing.stackexchange.com/questions/13023/why-didnt-the-6502-have-increase-decrease-opcodes-for-a – JeremyP Mar 26 '21 at 10:27
  • Actually seems unusual for that era to keep the same part number and change something significant, and/or create a datasheet that is incompatible with some parts bearing that number... – rackandboneman Sep 29 '21 at 22:03
  • 3
    You may be interested to know that this myth has been busted! For those who aren't going to watch the video, it is not a buggy ROR instruction, it's a missing feature. They didn't put in the ROR instruction until Revision D. That means that this answer actually does answer Leo B's question. – Omar and Lorraine Sep 07 '23 at 15:34
21

Are there any similar Western examples of an instruction set with obviously cut corners

Following on your example of having addition but not subtraction, the Intel 8080 has 8 bit addition and subtraction instructions laid out neatly as you can see in this table on rows 8x and 9x.

The 8080 also has a 16 bit addition instruction DAD with opcode 0x09, but there is no 16 bit subtraction. The logical place for it in the opcode table would be one column left at 0x08, but that is a NOP on the 8080. Most of the hardware necessary for subtraction is on the die. It just wasn't implemented for some reason.

On the 8085 there's even an undocumented opcode that does implement 16 bit subtraction at 0x08. Though unlike the 16 bit addition, it doesn't update the flags properly, which I suspect is why it's undocumented. You can find a table of the 8085 opcodes here.

Leo B.
  • 19,082
  • 5
  • 49
  • 141
RETRAC
  • 13,656
  • 3
  • 42
  • 65
  • Please improve your answer by mentioning the actual opcodes, including unused slots. Pointing to the 8080 opcode table, e.g. http://pastraiser.com/cpu/i8080/i8080_opcodes.html would have been helpful as well. – Leo B. Feb 01 '19 at 20:10
  • @LeoB. Feel free to make any additions you consider appropriate. – RETRAC Feb 01 '19 at 20:12
  • I'm not familiar with the 8080 architecture. What is the opcode of the 16 bit addition instruction you've mentioned? – Leo B. Feb 01 '19 at 20:14
  • @LeoB. The site you linked also has a table of 8085 opcodes at http://pastraiser.com/cpu/i8085/i8085_opcodes.html I will update my post since the dsub does appear in the table where you'd expect it. – RETRAC Feb 01 '19 at 20:15
  • It's exactly the same reason as I would assume with the BESM-6. Poiters are unsigned integer to address memory. While addition is useful to resolve adressing expressions, subtraction isn't as much. For the 8085 additions see here – Raffzahn Feb 01 '19 at 20:36
  • @Raffzahn Without subtraction or XOR, there was no way to compare pointers for equality. – Leo B. Feb 01 '19 at 20:44
  • 2
    @Raffzahn Yes, absolutely. Subtraction is less important to have since it can be synthesized. With pointers, a good assembler will handle negative constants so you can just do something like DAD -2 (0xFFFE) if you want to subtract 2. Subtraction at run time would however require generating the 2's complement of the subtrahend first, or chaining 8-bit subtractions. – RETRAC Feb 01 '19 at 20:49
  • @LeoB. True, but that again it might be an added requirement. Or can you prove that it has been part of the original list? These are all things that might be nice (like having an ADD on a 6502), but not a must to have. That's why all teh musings here are rather pointless. – Raffzahn Feb 01 '19 at 20:51
  • 3
    @Raffzahn Prove - no, but aliasing opcodes instead of making the extra one a no-op or an illegal instruction is unusual enough to raise suspicion. – Leo B. Feb 01 '19 at 20:59
  • @LeoB. Given, aliasing is unusual - unless it can be explained with saving resources. – Raffzahn Feb 01 '19 at 21:04
  • @Raffzahn That's exactly the point: apparently there were not enough resources left to wire the instruction as anything different, even as a no-op or a trapped one, let alone as something useful. – Leo B. Feb 01 '19 at 21:08
  • 4
    @LeoB. The BESM-6 is far from the only processor which doesn't bother to fully decode its instructions. The original NMOS 6502 was a minimal design, and they did not bother to fully decode the opcode space to turn unimplemented opcodes into NOPs. The opcodes in question behaved in a variety of ways: some would crash the processor, some behaved unreliably, some were useless for programming, and a few actually turned out to be useful by accident. This was certainly an intentional design choice to save die area. – RETRAC Feb 01 '19 at 21:12
  • @RETRAC Were there any obvious gaps in the 6502 set of instructions, similar to those in BESM-6 or 8080? – Leo B. Feb 01 '19 at 21:16
  • @LeoB. Yes, quite a few. The 6502 is infamous for addressing modes which are very idiosyncratic. For example, you can compare the accumulator to memory with any of the addressing modes, but the X index register can only be compared using immediate, absolute and zero page addressing. – RETRAC Feb 01 '19 at 21:22
  • And the opcodes which would correspond to comparing the X register to memory with any of the remaining addressing modes were unimplemented, or used for something else? If for something else, it doesn't count. – Leo B. Feb 01 '19 at 21:26
  • 1
    @LeoB. It's a mix of both. Based on the encoding of the CMP instruction, one might expect CPX with Y-indexed absolute addressing with opcode F8, but that sets decimal mode. On the other hand, ASL (arithmetic shift left) with the encoding specifying an immediate simply crashes the processor and requires a reset. – RETRAC Feb 01 '19 at 21:47
  • 1
    @RETRAC: More interestingly, the 6502 lacks an opcode for LDX (zp),y but an undocumented opcode will behave like a simultaneous LDA (zp),y and LDX (zp),y. Likewise, it lacks DEC (zp),y but includes an opcode that behaves like a simultaneous DEC (zp),y and a CMP with the value that results from the DEC. – supercat Mar 24 '21 at 19:12
6

Socialism is terrible - but there are other reasons for "cut corners" leading to missing instructions. For example, capitalism.

In the minicomputer era it was reasonably common for there two be two variants of a machine: one without floating point and one with. You paid more $$$$ for the one with.

I'm thinking specifically of the Honeywell 716 - but there were several others. One interesting thing about the 716: It wasn't a matter of the expense of the parts. The only motherboard had the parts. The difference between the 716 without FP and the 716 with FP was that to add FP you cut a trace on the motherboard.

(The general customer didn't know this of course. I know it because I worked for a Honeywell division that saved money by buying 716s without and using a xacto knife to turn them into 716s with.)

This isn't quite the same, to my mind, as whether you had a FP coprocessor or not, for machines that did that, as in the 8086/8087. I mean, it is sort of. But, it also isn't sort of. (Maybe someone can help me clarify this thought...)

(You can also quibble if you wish that this doesn't really answer the OP' question. Maybe not. But where else could I explain this?)

Omar and Lorraine
  • 38,883
  • 14
  • 134
  • 274
davidbak
  • 6,269
  • 1
  • 28
  • 34
  • 2
    Sort of like a Tesla with a battery software locked to less than full power. – manassehkatz-Moving 2 Codidact Feb 06 '19 at 02:22
  • 2
    @manassehkatz - Well, that's another story! Amdahl used to sell an IBM 360/370 compatible - forget the model number - that had a "turbo" switch on the front. (Forget the marketing name for it.) Most of the month you had something like a machine comparable to an IBM 370/148 or so, and that's what you were paying for. But, you know how you have that processing crunch at the end of the month to 'close the books'? You flipped the switch, or turned the dial, and instantly you had 20% more oomph. And you paid for that boost, on a meter, for a couple of days each month. First overclocking! – davidbak Feb 06 '19 at 02:35
  • 4
    That's not "blatantly missing", that's "deliberately put behind a paywall". :) – Leo B. Feb 06 '19 at 18:05
  • 1
    That's still the practice at Intel. All the features like ECC memory, transaction, hyperthreading instructions are lasered off to put in the different categories of i3,i5,i7 or i. – Patrick Schlüter Mar 25 '21 at 15:22
  • Though, to be fair, I guess you got an FP enabled system with support and warranty for an FP enabled system when you bought it as such. You just got the FP enabled system if you went for the xacto. – rackandboneman Apr 03 '21 at 19:04
  • 4
    @PatrickSchlüter however, this could also very well be a way to reuse dies where these features are defective in the first place. – rackandboneman Apr 03 '21 at 19:07
4

The Manchester 'Baby' famously had neither 'load accumulator with value from memory' nor 'add value from memory to accumulator'.

Rather, it had 'load negative' and 'subtract'. Nevertheless, these were sufficient to allow programs to be written, and in fact the Baby was the first operational stored-program digital computer.

The lack of ability to do any arithmetic other than negate or subtract was a consequence of its intent as a device for evaluating Williams Tube memory.

dave
  • 35,301
  • 3
  • 80
  • 160
2

Fairchild F8

There is "add to accumulator" but no subtract.

There is "decrement register" but no "increment register"

There is "increment accumulator" but no "decrement accumulator"

Grabul
  • 3,637
  • 16
  • 18
0

I'm surprised no one has brought up the System/360 Model 20 yet, a cost and instruction set reduced version of the /360 architecture.

Michael Graf
  • 10,030
  • 2
  • 36
  • 54
  • 1
    Maybe because it's not 'missing' instructions? The -20 is a 16 bit version of the basic /360 without FP, supervisor mode, no I/O processor and halve the registers. It includes all (16 bit) binary instructions, all BCD, all logical instructions and all addressing modes, but restricted to 16 bit words. There was nothing missing. In fact, up to ca. 1982 we operated several application using the same code base as for 'full' /370. The only difference, beside the need to be assembled to tape, was a different subroutine branch instruction (handled by macro anyway) . – Raffzahn Oct 22 '23 at 13:52