Hi there. The machine I'm working is part accumulator based, part register based. I'm having trouble figuring out how best to tell the compiler how ACC is affected and when.
For example, the add instruction is two operand with the destination being a general register: ADD, R11 is equivalent to R11 = R11 + ACC This works fine using a rule like (define_insn "addsi3_insn" [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_operand:SI 1 "register_operand" "0") (match_operand:SI 2 "register_operand" "b")))] (b is the constraint that the register comes from the ACC_REGS class) The logical right shift instruction only works on the accumulator: LSR1 is equivalent to ACC = ACC >> 1 This works fine using: (define_insn "lshrsi3_const" [(set (match_operand:SI 0 "register_operand" "=b") (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") (match_operand:SI 2 "immediate_operand" "")))] The problem is when I have to clobber ACC such as when moving between registers. The output should be: LOADACC, R10; STOREACC, R11 (equivalent to ACC = R10; R11 = ACC) I've tried a parallel clobber like: (define_insn "movsi" [(set (match_operand:SI 0 "nonimmediate_operand" "=b, dam,dam") (match_operand:SI 1 "general_operand" "dami,b, dam")) (clobber (reg:SI TREG_ACC)) but this causes trouble when setting up ACC for the likes of the add above. The compiler runs but the code is incorrect I've tried a parallel with a match_scratch like: (define_insn "movsi" [(set (match_operand:SI 0 "nonimmediate_operand" "=b, rm,rm") (match_operand:SI 1 "general_operand" "rmi,b, rm")) (clobber (match_scratch:SI 2 "=X,X,b")) ] "" "@ LOADACC, %1 STOREACC, %0 LOADACC, %1\;STOREACC, %0" This uses a 'b' constraint to put the scratch into ACC when moving between registers and a 'X' constraint to ignore the scratch when moving to or from ACC directly. This basically works but fails when mixed with other instructions. For example, the code: return left + right fails with a 'movsi does not meet constraints' as ACC was already allocated to one of the operands of the addsi, was not available for the scratch register, and as such something else was given to the movsi which didn't match the 'b' constraint. All of the other instructions are OK as I can clobber or mark ACC as an output reload to mark it as dirty. Even the 68hc11 is better off as it can directly move between any two registers :) Any ideas? Am I going about this the wrong way? My first port treated ACC as a fixed register which avoided all of this but generated too many loads and stores. Is there a way of using a register only if a chain of instructions use it? Can I peephole it in someway instead? -- Michael