Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/h8300/genmova.sh @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | 77e2b8dfacca |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 #!/bin/sh | |
2 # Generate mova.md, a file containing patterns that can be implemented | |
3 # using the h8sx mova instruction. | |
4 | |
5 echo ";; -*- buffer-read-only: t -*-" | |
6 echo ";; Generated automatically from genmova.sh" | |
7 | |
8 # Loop over modes for the source operand (the index). Only 8-bit and | |
9 # 16-bit indices are allowed. | |
10 for s in QI HI; do | |
11 | |
12 # Set $src to the operand syntax for this size of index. | |
13 case $s in | |
14 QI) src=%X1.b;; | |
15 HI) src=%T1.w;; | |
16 esac | |
17 | |
18 # A match_operand for the source. | |
19 operand="(match_operand:$s 1 \"h8300_dst_operand\" \"0,rQ\")" | |
20 | |
21 # Loop over the destination register's mode. The QI and HI versions use | |
22 # the same instructions as the SI ones, they just ignore the upper bits | |
23 # of the result. | |
24 for d in QI HI SI; do | |
25 | |
26 # If the destination is larger than the source, include a | |
27 # zero_extend/plus pattern. We could also match zero extensions | |
28 # of memory without the plus, but it's not any smaller or faster | |
29 # than separate insns. | |
30 case $d:$s in | |
31 SI:QI | SI:HI | HI:QI) | |
32 cat <<EOF | |
33 (define_insn "" | |
34 [(set (match_operand:$d 0 "register_operand" "=r,r") | |
35 (plus:$d (zero_extend:$d $operand) | |
36 (match_operand:$d 2 "immediate_operand" "i,i")))] | |
37 "TARGET_H8300SX" | |
38 "mova/b.l @(%o2,$src),%S0" | |
39 [(set_attr "length_table" "mova") | |
40 (set_attr "cc" "none")]) | |
41 | |
42 EOF | |
43 ;; | |
44 esac | |
45 | |
46 # Loop over the shift amount. | |
47 for shift in 1 2; do | |
48 case $shift in | |
49 1) opsize=w mult=2;; | |
50 2) opsize=l mult=4;; | |
51 esac | |
52 | |
53 # Calculate the mask of bits that will be nonzero after the source | |
54 # has been extended and shifted. | |
55 case $s:$shift in | |
56 QI:1) mask=510;; | |
57 QI:2) mask=1020;; | |
58 HI:1) mask=131070;; | |
59 HI:2) mask=262140;; | |
60 esac | |
61 | |
62 # There doesn't seem to be a well-established canonical form for | |
63 # some of the patterns we need. Emit both shift and multiplication | |
64 # patterns. | |
65 for form in mult ashift; do | |
66 case $form in | |
67 mult) amount=$mult;; | |
68 ashift) amount=$shift;; | |
69 esac | |
70 | |
71 case $d:$s in | |
72 # If the source and destination are the same size, we can treat | |
73 # mova as a sort of multiply-add instruction. | |
74 QI:QI | HI:HI) | |
75 cat <<EOF | |
76 (define_insn "" | |
77 [(set (match_operand:$d 0 "register_operand" "=r,r") | |
78 (plus:$d ($form:$d $operand | |
79 (const_int $amount)) | |
80 (match_operand:$d 2 "immediate_operand" "i,i")))] | |
81 "TARGET_H8300SX" | |
82 "mova/$opsize.l @(%o2,$src),%S0" | |
83 [(set_attr "length_table" "mova") | |
84 (set_attr "cc" "none")]) | |
85 | |
86 EOF | |
87 ;; | |
88 | |
89 # Handle the cases where the source is smaller than the | |
90 # destination. Sometimes combine will keep the extension, | |
91 # sometimes it will use an AND. | |
92 SI:QI | SI:HI | HI:QI) | |
93 | |
94 # Emit the forms that use zero_extend. | |
95 cat <<EOF | |
96 (define_insn "" | |
97 [(set (match_operand:$d 0 "register_operand" "=r,r") | |
98 ($form:$d (zero_extend:$d $operand) | |
99 (const_int $amount)))] | |
100 "TARGET_H8300SX" | |
101 "mova/$opsize.l @(0,$src),%S0" | |
102 [(set_attr "length_table" "mova_zero") | |
103 (set_attr "cc" "none")]) | |
104 | |
105 (define_insn "" | |
106 [(set (match_operand:$d 0 "register_operand" "=r,r") | |
107 (plus:$d ($form:$d (zero_extend:$d $operand) | |
108 (const_int $amount)) | |
109 (match_operand:$d 2 "immediate_operand" "i,i")))] | |
110 "TARGET_H8300SX" | |
111 "mova/$opsize.l @(%o2,$src),%S0" | |
112 [(set_attr "length_table" "mova") | |
113 (set_attr "cc" "none")]) | |
114 | |
115 EOF | |
116 | |
117 # Now emit the forms that use AND. When the index is a register, | |
118 # these forms are effectively $d-mode operations: the index will | |
119 # be a $d-mode REG or SUBREG. When the index is a memory | |
120 # location, we will have a paradoxical subreg such as: | |
121 # | |
122 # (and:SI (mult:SI (subreg:SI (mem:QI ...) 0) | |
123 # (const_int 4)) | |
124 # (const_int 1020)) | |
125 # | |
126 # Match the two case separately: a $d-mode register_operand | |
127 # or a $d-mode subreg of an $s-mode memory_operand. Match the | |
128 # memory form first since register_operand accepts mem subregs | |
129 # before reload. | |
130 memory="(match_operand:$s 1 \"memory_operand\" \"m\")" | |
131 memory="(subreg:$d $memory 0)" | |
132 register="(match_operand:$d 1 \"register_operand\" \"0\")" | |
133 for paradoxical in "$memory" "$register"; do | |
134 cat <<EOF | |
135 (define_insn "" | |
136 [(set (match_operand:$d 0 "register_operand" "=r") | |
137 (and:$d ($form:$d $paradoxical | |
138 (const_int $amount)) | |
139 (const_int $mask)))] | |
140 "TARGET_H8300SX" | |
141 "mova/$opsize.l @(0,$src),%S0" | |
142 [(set_attr "length_table" "mova_zero") | |
143 (set_attr "cc" "none")]) | |
144 | |
145 (define_insn "" | |
146 [(set (match_operand:$d 0 "register_operand" "=r") | |
147 (plus:$d (and:$d ($form:$d $paradoxical | |
148 (const_int $amount)) | |
149 (const_int $mask)) | |
150 (match_operand:$d 2 "immediate_operand" "i")))] | |
151 "TARGET_H8300SX" | |
152 "mova/$opsize.l @(%o2,$src),%S0" | |
153 [(set_attr "length_table" "mova") | |
154 (set_attr "cc" "none")]) | |
155 | |
156 EOF | |
157 done | |
158 ;; | |
159 esac | |
160 done | |
161 done | |
162 done | |
163 done |