I am porting gcc-4.4.3 to TILE-Gx, a 64-bit VLIW RISC. It's gone pretty well so far; most tests work, Linux builds, etc. Thanks for writing such good documentation.
This chip, like MIPS64, maintains the invariant that SImode values in DImode registers are always sign-extended. So I have implemented PROMOTE_MODE, TARGET_MODE_REP_EXTENDED and LOAD_EXTEND_OP accordingly, and made sure my .md file always preserves this invariant. This almost works, but testing has shown two cases that break this invariant, and I want to know if it's my fault. The problem is that 'widen_bswap' and 'expand_divmod' each produce a DImode value whose high 32 bits are known to be zero, and then simply 'gen_lowpart' the DImode value to convert it to SImode. This produces a SUBREG, not a 'truncate' rtx, so I end up with a register that is incorrectly zero-extended. Am I doing something wrong, or are these functions incorrect? As far as I can tell, gen_lowpart is not expected to force a sign-extension operation. But SUBREG rules are a bit subtle so I could be missing something. Everything works fine if I modify 'widen_bswap' and 'expand_divmod' to do this instead of 'return gen_lowpart (mode, x)': return simplify_gen_unary (TRUNCATE, mode, x, GET_MODE (x)); Since the high bits are already zero, that would be less efficient on most platforms, so guarding it with something like this would probably be smarter: if (targetm.mode_rep_extended (mode, GET_MODE(x)) == SIGN_EXTEND) return simplify_gen_unary (TRUNCATE, mode, x, GET_MODE (x)); I'm happy to believe I'm doing something wrong in my back end, but I'm not sure what that would be. I could also believe these are obscure edge cases no one cared about before. Any tips would be appreciated. Thanks! -Mat