We would like to eliminate cc0 and the associated machinery from the compiler, because it is complicated and not supported on popular or modern processors. Here is a plan which I think could accomplish that without unreasonable effort.
1) Modify the programs which read the .md file to look for an attribute named clobbercc. If such an attribute exists, then for any instruction pattern which defines clobbercc as "yes" (or "true", or whatever), automatically add "(clobber (reg:CC CC_REG))" to the instruction. 2) For each target which uses CC: 2a) Define the clobbercc attribute to be "yes" for each insn which changes the condition codes unpredictably. Typically the default would be "yes", and then either clobbercc would be written to use cond to select instruction for which it should be "no", or those instructions would be marked specifically. 2b) Convert conditional branch instructions from separate cmpMODE/bCOND instructions to a single conditional branch instruction, either by saving condition codes in cmpMODE or tstMODE or by using cbranch. 2c) Similarly convert setCOND, movCOND, and addCOND instructions. 2d) For each converted instruction, write a splitter which takes effect after reload and splits the instruction into the comparison and the branch (or whatever). The comparison should set CC_REG, and the branch should test CC_REG. 2e) Rewrite all other instruction patterns which set cc0 to instead set CC_REG (and make sure that the clobbercc attribute is not "yes" for such instructions). Rewrite instruction patterns which test cc0 to instead test CC_REG. At this point we have eliminated cc0 for the target. The generated code should be correct. The instruction which sets the condition codes will be kept in synch with the instruction which uses the condition codes, because most other instructions will have an automatically inserted clobber. However, the generated code will not be as good, because there will be unnecessary comparison instructions. (A note for the uninitiated. We need to write the converted branch instructions as single instructions which are split after reload because reload has to be able to move values in and out of memory, and compute addresses, between arbitrary pairs of instructions. On cc0 machines, those moves and computations will themselves change the condition codes, and we will wind up testing the wrong conditions in the branch instruction. So reload has to see compare-and-branch as a single instruction.) 3) Write a new optimization pass enabled on targets which define NOTICE_UPDATE_CC. I think this pass would be run just before machine dependent reorg, although perhaps there is a better place for it. Walk through the instructions, calling NOTICE_UPDATE_CC on each one. When we find an instruction which sets CC_REG, check the source of the set with the current CC status, just as final_scan_insn does now. If the current CC status is the same, delete the instruction which sets CC_REG. At this point, the generated code quality should be approximately the same as when the target used cc0. 4) When all targets have been converted, remove all the code in the compiler protected by #ifdef HAVE_cc0. Remove the CC_SETTER and CC_USER register notes. Remove the associated documentation. 5) Profit! The main ideas here are to use the clobbercc attribute to avoid having to modify every single instruction, and to use the new optimization pass to avoid having to write dozens of new peepholes to recover code quality. The conversions in steps 2b through 2e above are relatively mechanical. Step 2a will require a bit of thought, but should not be too difficult. Does anybody see any problems with this approach? Does anybody think this is, or is not, implementable? Does anybody think there is an approach which is simpler? Ian