Monthly Archives: September 2006

Strange SSE3 opcodes

Intel used some strange opcodes for the SSE3 instructions. All MMX/SSE opcodes use the 0x0f prefix (former “pop cs”). They soon noticed the the 0x0f area gets full, so they used the 0x66, 0xf2, 0xf3 prefix as modifiers. The basic rule is:

  • 0x66: makes MMX-intructions use the xmm registers; for SSE instructions this switches from packed single to packed double
  • 0xf3: for SSE-instructions: use the scalar single form
  • 0xf2: for SSE-instructions: use the scalar double form

The isn’t always 100% correct, so you need different tables for 0xf2, 0xf3 form anyway, when writing a disassembler. Example

  • 0fdb: pand mmx, mmx
  • 660fdb: pand xmm, xmm
  • 0f58: addps
  • 660f58: addpd
  • f30f58: addss
  • f20f58: addsd

But some of the SSE3 instructions (addsubps, addsubpd, haddps, haddpd, hsubps, haddps) just seem to be placed at random. By the scheme above, one would expect that addsubps/d share the same opcode and you switch between them with the 0x66 prefix. But they used:

  • f20fd0.. addsubps
  • 660fd0.. addsubpd
  • 0fd0 and f30fd0 are both invalid

When I first saw this, I thought this is just an error in the tables. Do you have an idea why they didn’t used 0fd0 for addsubps and 660fd0 for addsubpd?