On 08/09/2015 01:13 PM, Laurent Vivier wrote:
   m68k: allow to update flags with operation on words and bytes
   m68k: update CPU flags management
   m68k: add X flag helpers

I wonder if we can talk about a different mechanism for tracking flags.

The x86 scheme tracks flags with 3 words: { op, dest, src }. This is easy to handle arithmetic, logicals, and comparisons. But shifts and other weird things require complex helpers.

The m68k scheme, which you're enhancing, is the same, except with an additional word for X. It's this extra X flag that complicates things.

The arm scheme tracks 4 flags with 4 individual words. This is more complicated for arithmetic (especially computing overflow), but it rarely requires complicated helpers.

I propose using a hybrid between the two, using 6 words: { op, c, v, z, n, x }.

op = OP_FLAGS (i.e. fully computed state)

  X = cc_x is 0/1
  C = cc_c is 0/1
  V = cc_v < 0
  N = cc_n < 0
  Z = cc_z == 0

op = OP_ADD

  X = C = cc_x is 0/1

  cc_n = result
  cc_v = src1
  cc_c = unused
  cc_z = unused

  N = cc_n < 0
  Z = cc_n == 0
  V = ((result ^ src1) & ~((result - src1) ^ src1)) < 0

op = OP_SUB

  like OP_ADD, except
  V = ((result ^ src1) & (src1 ^ (src1 - result))) < 0

op = OP_LOGIC

  X = cc_x is 0/1
  C = 0
  V = 0

  cc_n = result
  N = cc_n < 0
  Z = cc_n == 0

All of the byte and word variants are handled by sign-extending the quantities.

This keeps X up-to-date at all times. It minimizes the amount to data that needs to be synced back to env before memory operations. It leaves enough data to easily compute signed comparisons.

The more complicated cases of addx and shifts, now simply operate in OP_FLAGS mode and don't require helpers.

I'll follow up with some patches...


r~

Reply via email to