This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Difficulty matching machine description to target - any way to specify a minimum register width ?


I've been trying off and on for a couple of days to create a machine description that handles the following target and produces the output I am hoping for.

The CPU has a 16 bit word size - and only has word size registers. As a consequence it sign or zero extends when loading byte operands - depending on the instruction used.

In addition this is a two address machine so binary operators have the form

Rn op= operand
e.g.

add r0,r1
add r0,[memory]

or when referencing Signed Byte (bs) operands in memory

addBS r0,[byte value address]

compiling

signed char ch1, ch2;

void f( void )
{
ch1 += ch;
}

gives an assembly output of
(1)
movbs r1,[_ch1]
movbs r2,[_ch2]
add r1,r2
stb r1,[ch1

Based on this error message ...

(insn 9 8 10 3 (set (reg:QI 19 [ ch1.4 ]) <-- non_strict_ (pre-reload/regalloc) ? -> reg:QI plus:HI HI HI
(plus:HI (reg:HI 21)
(sign_extend:HI (reg:QI 22)))) t.c:6 -1


when using this pattern ...

(define_insn "addqi3i"
[(set (match_operand:HI 0 "register_operand" "=r")
(plus:HI (match_operand:HI 1 "register_operand" "%0")
(sign_extend:HI (match_operand:QI 2 "memory_operand" "m"))))]

I altered the pattern to...

(define_insn "addqi3"
[(set (match_operand:QI 0 "register_operand" "=r")
(truncate:QI
(plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
(sign_extend:HI (match_operand:QI 2 "memory_operand" "m")))))]
""
"addbs %0,[%2]"
[(set_attr "length" "2")]
)

I then get an assembly output of ...
(2)
movbs r1,[_ch1] ;# 5 *movqi_insn/3 [length = 2]
addbs r1,[_ch2] ;# 6 addqi3 [length = 2]
stb r1,[_ch1] ;# 7 *movqi_insn/4 [length = 2]

which is exactly what I was after. The problem comes when compiling an expression matching a mix of int and char operands - the above addqi3 pattern causes

t.c: In function ‘f’:
t.c:14:1: error: unrecognisable insn:
(insn 8 7 9 3 (set (reg:QI 26)
(truncate:QI (plus:HI (sign_extend:HI (reg:QI 24))
(sign_extend:HI (reg:QI 25))))) t.c:6 -1
(nil))
t.c:14:1: internal compiler error: in extract_insn, at recog.c:2109

changing the addqi3 pattern to

(define_insn "addqi3i"
[(set (match_operand:HI 0 "register_operand" "=r")
(plus:HI (match_operand:HI 1 "register_operand" "%0")
(sign_extend:HI (match_operand:QI 2 "memory_operand" "m"))))]

Fixes this, however when adding two bytes together I now get the suboptimal output shown in (1) above.

I've tried using a define_expand for addqi3 and then including both the addqi3 patterns above (with custom names) as specialisations - however at least one of the specialisations isn't used when I do this.

Can anyone give me an idea what patterns I should be using to address this problem ? I've tried looking at the combine dump to see what gcc is expecting but that hasn't been of much help.

The word width instructions work perfectly so I assumed that the sign/zero extension was the problem. I have trawled the gcc internals docs to see if there is a way to tell gcc that the target doesn't have registers narrower than a word - in the hope that I could prevent gcc from requiring the reg:QI 19 in ...

(insn 9 8 10 3 (set (reg:QI 19 [ ch1.4 ]) <-- non_strict_ (pre-reload/regalloc) ? -> reg:QI plus:HI HI HI
(plus:HI (reg:HI 21)
(sign_extend:HI (reg:QI 22)))) t.c:6 -1


and haven't found anything to help ?

Any advice would be greatly appreciated.

Cheers, Paul.























Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]