Hello all, The target that i am working on is 16bit, big endian and with 16 registers. It has this particular addressing mode
load Rd, Ra[offset] store Rs, Ra[offset] where the offset should be positive, base register Ra should be an even register and for the source or the destination register Rd/Ra, the restriction is that it should be one more than the base register . So the following instructions are valid: load R5, R4[4] store R11, R10[2] while the following ones are wrong: load R8, R6[4] store R3, R8[2] What i did to implement this is to have eight register classes with each class having two registers, an even register and an odd register then in define expand look for the register indirect with offset addressing mode and emit gen_store_offset or gen_load_offset pattern if the addressing mode is found. In the pattern i will have the 8 similar constraints for the base register and the source/destination register. But this didn't work out properly, probably because i had many patterns for movhi operations. So i tired what Jim Wilson suggested to me when i posted this question earlier. What he suggested was: "One thing you could try is generating a double-word pseudo-reg at RTL expand time, and then using subreg 0 for the source and subreg 1 for the dest (or vice versa depending on endianness/word order). This will get you a register pair you can use from the register allocator. This doesn't help at reload time though. You probably have to define a constraint for every register, and then write an alternative for every register pair matching the correct even register with the correct odd register. That gets you past reload." So i did the following to implement his suggestion. I have single define_expand and define_insn for movhi patterns. In define_expand for movhi i have the folllowing offset = INTVAL(XEXP(XEXP(mem_op, 0), 1)); dword = gen_reg_rtx (SImode); base = simplify_gen_subreg (HImode, dword, SImode, 0); if (mode == Pmode) { reg_op = simplify_gen_subreg (HImode, dword, SImode, 2); mem_op1 = gen_rtx_MEM (Pmode, plus_constant (base, offset)); } else { reg_op = simplify_gen_subreg (QImode, dword, SImode, 3); mem_op1 = gen_rtx_MEM (QImode, plus_constant (base, offset)); } if (GET_CODE (operands[0]) == MEM) { operands[0] = mem_op1; operands[1] = reg_op; } else if (GET_CODE (operands[1]) == MEM) { operands[1] = mem_op1; operands[0] = reg_op; } and in define_insn i have the following pattern: (define_insn "*movhi_internal" [(set (match_operand:HI 0 "nonimmediate_operand" "=r,R01,R03,R05,R07,R09,R13,R15,r,U00,U02,U04,U06,U08,U12,U14,m,r") (match_operand:HI 1 "general_operand" "r,U00,U02,U04,U06,U08,U12,U14,m,R01,R03,R05,R07,R09,R13,R15,r,i"))] where Uxx is memory constraints and Rxx is register constraints. After implementing this i came across this problem: (insn 12 11 13 1 (set (reg/f:HI 24) (mem/c/i:HI (reg/f:HI 25) [0 m+0 S2 A16])) -1 (nil) (nil)) (insn 13 12 14 1 (set (subreg:QI (reg:SI 28) 3) (mem:QI (plus:HI (subreg:HI (reg:SI 28) 0) (const_int 1 [0x1])) [0 S1 A8])) -1 (nil) (nil)) (insn 14 13 15 1 (set (reg:HI 26) (zero_extend:HI (reg:QI 27))) -1 (nil) (nil)) For zero-extend both operands should be in registers. So one operand which was previously in memory is moved to reg27 through load operations(insn 13). Since for this offset addressing mode is used define_expand for movqi will generate SImode register, reg28 and does the operations. But this is not reflected in the subsequent instructions (insn 14). And hence insn 13 is getting deleted as its operands are never used. What i am i doing wrong? Am i implementing the addressing mode properly? Any help is appreciated. Regards, Shafi