修订版 | 6065c6125174e6a392de83d2bbd1598350149732 (tree) |
---|---|
时间 | 2018-12-21 17:33:27 |
作者 | Yoshinori Sato <ysato@user...> |
Commiter | Yoshinori Sato |
RXv3 support
@@ -39,7 +39,8 @@ enum rx_cpu_types | ||
39 | 39 | RX610, |
40 | 40 | RX200, |
41 | 41 | RX100, |
42 | - RXV2 | |
42 | + RXV2, | |
43 | + RXV3 | |
43 | 44 | }; |
44 | 45 | |
45 | 46 | extern int rx_pid_register; |
@@ -57,6 +58,7 @@ extern void rx_op (expressionS, int, int); | ||
57 | 58 | extern void rx_disp3 (expressionS, int); |
58 | 59 | extern void rx_field5s (expressionS); |
59 | 60 | extern void rx_field5s2 (expressionS); |
61 | +extern void rx_bfield (expressionS, expressionS, expressionS); | |
60 | 62 | extern void rx_relax (int, int); |
61 | 63 | extern void rx_linkrelax_dsp (int); |
62 | 64 | extern void rx_linkrelax_imm (int); |
@@ -64,6 +66,7 @@ extern void rx_linkrelax_branch (void); | ||
64 | 66 | extern int rx_parse (void); |
65 | 67 | extern int rx_wrap (void); |
66 | 68 | extern void rx_note_string_insn_use (void); |
69 | +extern void rx_post (char); | |
67 | 70 | |
68 | 71 | extern char * rx_lex_start; |
69 | 72 | extern char * rx_lex_end; |
@@ -33,6 +33,7 @@ static int rx_lex (void); | ||
33 | 33 | #define BSIZE 0 |
34 | 34 | #define WSIZE 1 |
35 | 35 | #define LSIZE 2 |
36 | +#define DSIZE 3 | |
36 | 37 | |
37 | 38 | /* .sb .sw .l .uw */ |
38 | 39 | static int sizemap[] = { BSIZE, WSIZE, LSIZE, WSIZE }; |
@@ -90,6 +91,8 @@ static int sizemap[] = { BSIZE, WSIZE, LSIZE, WSIZE }; | ||
90 | 91 | #define PC2(v) rx_op (v, 2, RXREL_PCREL) |
91 | 92 | #define PC3(v) rx_op (v, 3, RXREL_PCREL) |
92 | 93 | |
94 | +#define POST(v) rx_post (v) | |
95 | + | |
93 | 96 | #define IMM_(v,pos,size) F (immediate (v, RXREL_SIGNED, pos, size), pos, 2); \ |
94 | 97 | if (v.X_op != O_constant && v.X_op != O_big) rx_linkrelax_imm (pos) |
95 | 98 | #define IMM(v,pos) IMM_ (v, pos, 32) |
@@ -116,6 +119,7 @@ static int displacement (expressionS, int); | ||
116 | 119 | static void rtsd_immediate (expressionS); |
117 | 120 | static void rx_range (expressionS, int, int); |
118 | 121 | static void rx_check_v2 (void); |
122 | +static void rx_check_v3 (void); | |
119 | 123 | |
120 | 124 | static int need_flag = 0; |
121 | 125 | static int rx_in_brackets = 0; |
@@ -137,36 +141,37 @@ static int sub_op2; | ||
137 | 141 | expressionS exp; |
138 | 142 | } |
139 | 143 | |
140 | -%type <regno> REG FLAG CREG BCND BMCND SCCND ACC | |
144 | +%type <regno> REG FLAG CREG BCND BMCND SCCND ACC DREG DREGH DREGL DCREG DCMP | |
141 | 145 | %type <regno> flag bwl bw memex |
142 | 146 | %type <exp> EXPR disp |
143 | 147 | |
144 | -%token REG FLAG CREG ACC | |
148 | +%token REG FLAG CREG ACC DREG DREGH DREGL DCREG | |
145 | 149 | |
146 | 150 | %token EXPR UNKNOWN_OPCODE IS_OPCODE |
147 | 151 | |
148 | -%token DOT_S DOT_B DOT_W DOT_L DOT_A DOT_UB DOT_UW | |
152 | +%token DOT_S DOT_B DOT_W DOT_L DOT_A DOT_UB DOT_UW DOT_D | |
149 | 153 | |
150 | 154 | %token ABS ADC ADD AND_ |
151 | -%token BCLR BCND BMCND BNOT BRA BRK BSET BSR BTST | |
155 | +%token BCLR BCND BFMOV BFMOVZ BMCND BNOT BRA BRK BSET BSR BTST | |
152 | 156 | %token CLRPSW CMP |
153 | -%token DBT DIV DIVU | |
157 | +%token DABS DADD DBT DCMP DDIV DIV DIVU DMOV DMUL DNEG | |
158 | +%token DPOPM DPUSHM DROUND DSQRT DSUB DTOF DTOI DTOU | |
154 | 159 | %token EDIV EDIVU EMACA EMSBA EMUL EMULA EMULU |
155 | -%token FADD FCMP FDIV FMUL FREIT FSUB FSQRT FTOI FTOU | |
156 | -%token INT ITOF | |
160 | +%token FADD FCMP FDIV FMUL FREIT FSUB FSQRT FTOD FTOI FTOU | |
161 | +%token INT ITOD ITOF | |
157 | 162 | %token JMP JSR |
158 | 163 | %token MACHI MACLH MACLO MAX MIN MOV MOVCO MOVLI MOVU MSBHI MSBLH MSBLO MUL |
159 | -%token MULHI MULLH MULLO MULU MVFACHI MVFACGU MVFACMI MVFACLO MVFC MVTACGU | |
160 | -%token MVTACHI MVTACLO MVTC MVTIPL | |
164 | +%token MULHI MULLH MULLO MULU MVFACHI MVFACGU MVFACMI MVFACLO MVFC MVFDC | |
165 | +%token MVFDR MVTACGU MVTACHI MVTACLO MVTC MVTDC MVTIPL | |
161 | 166 | %token NEG NOP NOT |
162 | 167 | %token OR |
163 | 168 | %token POP POPC POPM PUSH PUSHA PUSHC PUSHM |
164 | 169 | %token RACL RACW RDACL RDACW REIT REVL REVW RMPA ROLC RORC ROTL ROTR ROUND |
165 | -%token RTE RTFI RTS RTSD | |
166 | -%token SAT SATR SBB SCCND SCMPU SETPSW SHAR SHLL SHLR SMOVB SMOVF | |
170 | +%token RSTR RTE RTFI RTS RTSD | |
171 | +%token SAT SATR SAVE SBB SCCND SCMPU SETPSW SHAR SHLL SHLR SMOVB SMOVF | |
167 | 172 | %token SMOVU SSTR STNZ STOP STZ SUB SUNTIL SWHILE |
168 | 173 | %token TST |
169 | -%token UTOF | |
174 | +%token UTOD UTOF | |
170 | 175 | %token WAIT |
171 | 176 | %token XCHG XOR |
172 | 177 |
@@ -630,7 +635,7 @@ statement : | ||
630 | 635 | | DIV { sub_op = 8; } op_dp20_rim |
631 | 636 | | DIVU { sub_op = 9; } op_dp20_rim |
632 | 637 | | TST { sub_op = 12; } op_dp20_rim |
633 | - | XOR { sub_op = 13; } op_dp20_rim | |
638 | + | XOR { sub_op = 13; } op_xor | |
634 | 639 | | NOT { sub_op = 14; sub_op2 = 0; } op_dp20_rr |
635 | 640 | | STZ { sub_op = 14; sub_op2 = 0; } op_dp20_ri |
636 | 641 | | STNZ { sub_op = 15; sub_op2 = 1; } op_dp20_ri |
@@ -738,17 +743,17 @@ statement : | ||
738 | 743 | | MVFACLO { sub_op = 1; } mvfa_op |
739 | 744 | | RACW '#' EXPR |
740 | 745 | { id24 (2, 0x18, 0x00); |
741 | - if (rx_uintop ($3, 4) && $3.X_add_number == 1) | |
746 | + if (rx_uintop ($3, 4) && exp_val($3) == 1) | |
742 | 747 | ; |
743 | - else if (rx_uintop ($3, 4) && $3.X_add_number == 2) | |
748 | + else if (rx_uintop ($3, 4) && exp_val($3) == 2) | |
744 | 749 | F (1, 19, 1); |
745 | 750 | else |
746 | 751 | as_bad (_("RACW expects #1 or #2"));} |
747 | 752 | | RACW '#' EXPR ',' ACC |
748 | 753 | { rx_check_v2 (); id24 (2, 0x18, 0x00); F ($5, 16, 1); |
749 | - if (rx_uintop ($3, 4) && $3.X_add_number == 1) | |
754 | + if (rx_uintop ($3, 4) && exp_val($3) == 1) | |
750 | 755 | ; |
751 | - else if (rx_uintop ($3, 4) && $3.X_add_number == 2) | |
756 | + else if (rx_uintop ($3, 4) && exp_val($3) == 2) | |
752 | 757 | F (1, 19, 1); |
753 | 758 | else |
754 | 759 | as_bad (_("RACW expects #1 or #2"));} |
@@ -903,6 +908,99 @@ statement : | ||
903 | 908 | as_bad (_("RDACW expects #1 or #2"));} |
904 | 909 | |
905 | 910 | /* ---------------------------------------------------------------------- */ |
911 | + | BFMOV { rx_check_v3(); sub_op = 1; } op_bfield | |
912 | + | BFMOVZ { rx_check_v3(); sub_op = 0; } op_bfield | |
913 | + | |
914 | +/* ---------------------------------------------------------------------- */ | |
915 | + | RSTR { rx_check_v3(); sub_op = 0; } op_save_rstr | |
916 | + | SAVE { rx_check_v3(); sub_op = 1; } op_save_rstr | |
917 | + | |
918 | +/* ---------------------------------------------------------------------- */ | |
919 | + | DABS { rx_check_v3(); sub_op = 0x0c; sub_op2 = 0x01; } double2_op | |
920 | + | DNEG { rx_check_v3(); sub_op = 0x0c; sub_op2 = 0x02; } double2_op | |
921 | + | DROUND { rx_check_v3(); sub_op = 0x0d; sub_op2 = 0x0d; } double2_op | |
922 | + | DSQRT { rx_check_v3(); sub_op = 0x0d; sub_op2 = 0x00; } double2_op | |
923 | + | DTOF { rx_check_v3(); sub_op = 0x0d; sub_op2 = 0x0c; } double2_op | |
924 | + | DTOI { rx_check_v3(); sub_op = 0x0d; sub_op2 = 0x08;} double2_op | |
925 | + | DTOU { rx_check_v3(); sub_op = 0x0d; sub_op2 = 0x09; } double2_op | |
926 | + | DADD { rx_check_v3(); sub_op = 0x00; } double3_op | |
927 | + | DDIV { rx_check_v3(); sub_op = 0x05; } double3_op | |
928 | + | DMUL { rx_check_v3(); sub_op = 0x02; } double3_op | |
929 | + | DSUB { rx_check_v3(); sub_op = 0x01; } double3_op | |
930 | + | DCMP DREG ',' DREG { rx_check_v3(); | |
931 | + B4(0x76, 0x90, 0x08, 0x00); F($1, 24, 4); F($2, 28, 4); F($4, 16, 4); } | |
932 | + | DMOV DOT_D REG ',' DREGH | |
933 | + { rx_check_v3(); | |
934 | + B4(0xfd, 0x77, 0x80, 0x03); F($3, 20, 4); F($5, 24, 4); } | |
935 | + | DMOV DOT_L REG ',' DREGH | |
936 | + { rx_check_v3(); | |
937 | + B4(0xfd, 0x77, 0x80, 0x02); F($3, 20, 4); F($5, 24, 4); } | |
938 | + | DMOV DOT_L REG ',' DREGL | |
939 | + { rx_check_v3(); | |
940 | + B4(0xfd, 0x77, 0x80, 0x00); F($3, 20, 4); F($5, 24, 4); } | |
941 | + | DMOV DOT_L DREGH ',' REG | |
942 | + { rx_check_v3(); | |
943 | + B4(0xfd, 0x75, 0x80, 0x02); F($3, 24, 4); F($5, 20, 4); } | |
944 | + | DMOV DOT_L DREGL ',' REG | |
945 | + { rx_check_v3(); | |
946 | + B4(0xfd, 0x75, 0x80, 0x00); F($3, 24, 4); F($5, 20, 4); } | |
947 | + | DMOV DOT_D DREG ',' DREG | |
948 | + { rx_check_v3(); | |
949 | + B4(0x76, 0x90, 0x0c, 0x00); F($3, 16, 4); F($5, 24, 4); } | |
950 | + | DMOV DOT_D DREG ',' '[' REG ']' | |
951 | + { rx_check_v3(); | |
952 | + B4(0xfc, 0x78, 0x08, 0x00); F($6, 16, 4); F($3, 24, 4); } | |
953 | + | DMOV DOT_D DREG ',' disp '[' REG ']' | |
954 | + { rx_check_v3(); | |
955 | + B3(0xfc, 0x78, 0x08); F($7, 16, 4); DSP($5, 14, DSIZE); | |
956 | + POST($3 << 4); } | |
957 | + | DMOV DOT_D '[' REG ']' ',' DREG | |
958 | + { rx_check_v3(); | |
959 | + B4(0xfc, 0xc8, 0x08, 0x00); F($4, 16, 4); F($7, 24, 4); } | |
960 | + | DMOV DOT_D disp '[' REG ']' ',' DREG | |
961 | + { rx_check_v3(); | |
962 | + B3(0xfc, 0xc8, 0x08); F($5, 16, 4); DSP($3, 14, DSIZE); | |
963 | + POST($8 << 4); } | |
964 | + | DMOV DOT_D '#' EXPR ',' DREGH | |
965 | + { rx_check_v3(); | |
966 | + B3(0xf9, 0x03, 0x03); F($6, 16, 4); IMM($4, -1); } | |
967 | + | DMOV DOT_L '#' EXPR ',' DREGH | |
968 | + { rx_check_v3(); | |
969 | + B3(0xf9, 0x03, 0x02); F($6, 16, 4); IMM($4, -1); } | |
970 | + | DMOV DOT_L '#' EXPR ',' DREGL | |
971 | + { rx_check_v3(); | |
972 | + B3(0xf9, 0x03, 0x00); F($6, 16, 4); IMM($4, -1); } | |
973 | + | DPOPM DOT_D DREG '-' DREG | |
974 | + { rx_check_v3(); | |
975 | + B3(0x75, 0xb8, 0x00); F($3, 16, 4); F($5 - $3, 20, 4); } | |
976 | + | DPOPM DOT_L DCREG '-' DCREG | |
977 | + { rx_check_v3(); | |
978 | + B3(0x75, 0xa8, 0x00); F($3, 16, 4); F($5 - $3, 20, 4); } | |
979 | + | DPUSHM DOT_D DREG '-' DREG | |
980 | + { rx_check_v3(); | |
981 | + B3(0x75, 0xb0, 0x00); F($3, 16, 4); F($5 - $3, 20, 4); } | |
982 | + | DPUSHM DOT_L DCREG '-' DCREG | |
983 | + { rx_check_v3(); | |
984 | + B3(0x75, 0xa0, 0x00); F($3, 16, 4); F($5 - $3, 20, 4); } | |
985 | + | MVFDC DCREG ',' REG | |
986 | + { rx_check_v3(); | |
987 | + B4(0xfd, 0x75, 0x80, 0x04); F($2, 24, 4); F($4, 20, 4); } | |
988 | + | MVFDR | |
989 | + { rx_check_v3(); B3(0x75, 0x90, 0x1b); } | |
990 | + | MVTDC REG ',' DCREG | |
991 | + { rx_check_v3(); | |
992 | + B4(0xfd, 0x77, 0x80, 0x04); F($2, 24, 4); F($4, 20, 4); } | |
993 | + | FTOD REG ',' DREG | |
994 | + { rx_check_v3(); | |
995 | + B4(0xfd, 0x77, 0x80, 0x0a); F($2, 24, 4); F($4, 20, 4); } | |
996 | + | ITOD REG ',' DREG | |
997 | + { rx_check_v3(); | |
998 | + B4(0xfd, 0x77, 0x80, 0x09); F($2, 24, 4); F($4, 20, 4); } | |
999 | + | UTOD REG ',' DREG | |
1000 | + { rx_check_v3(); | |
1001 | + B4(0xfd, 0x77, 0x80, 0x0d); F($2, 24, 4); F($4, 20, 4); } | |
1002 | + | |
1003 | +/* ---------------------------------------------------------------------- */ | |
906 | 1004 | |
907 | 1005 | ; |
908 | 1006 |
@@ -1048,6 +1146,34 @@ mvfa_op | ||
1048 | 1146 | as_bad (_("IMM expects #0 to #2"));} |
1049 | 1147 | ; |
1050 | 1148 | |
1149 | +op_xor | |
1150 | + : op_dp20_rim | |
1151 | + | REG ',' REG ',' REG | |
1152 | + { rx_check_v3(); B3(0xff,0x60,0x00), F ($5, 12, 4), F ($1, 16, 4), F ($3, 20, 4); } | |
1153 | + ; | |
1154 | + | |
1155 | +op_bfield | |
1156 | + : { rx_check_v3(); } | |
1157 | + '#' EXPR ',' '#' EXPR ',' '#' EXPR ',' REG ',' REG | |
1158 | + { B3(0xfc, 0x5a + (sub_op << 2), 0); F($11, 16, 4); F($13, 20, 4); | |
1159 | + rx_bfield($3, $6, $9);} | |
1160 | + ; | |
1161 | + | |
1162 | +op_save_rstr | |
1163 | + : '#' EXPR | |
1164 | + { B3(0xfd,0x76,0xe0 + (sub_op << 4)); UO1($2); } | |
1165 | + | REG | |
1166 | + { B4(0xfd,0x76,0xc0 + (sub_op << 4), 0x00); F($1, 20, 4); } | |
1167 | + ; | |
1168 | + | |
1169 | +double2_op | |
1170 | + : DREG ',' DREG | |
1171 | + { B4(0x76, 0x90, sub_op, sub_op2); F($1, 16, 4); F($3, 24, 4);} | |
1172 | + | |
1173 | +double3_op | |
1174 | + : DREG ',' DREG ',' DREG | |
1175 | + { B4(0x76, 0x90, sub_op, 0x00); F($1, 28, 4); F($3, 16,4); F($5, 24, 4);} | |
1176 | + | |
1051 | 1177 | /* ====================================================================== */ |
1052 | 1178 | |
1053 | 1179 | disp : { $$ = zero_expr (); } |
@@ -1135,6 +1261,66 @@ token_table[] = | ||
1135 | 1261 | { "bbpsw", CREG, 24 }, |
1136 | 1262 | { "bbpc", CREG, 25 }, |
1137 | 1263 | |
1264 | + { "dr0", DREG, 0 }, | |
1265 | + { "dr1", DREG, 1 }, | |
1266 | + { "dr2", DREG, 2 }, | |
1267 | + { "dr3", DREG, 3 }, | |
1268 | + { "dr4", DREG, 4 }, | |
1269 | + { "dr5", DREG, 5 }, | |
1270 | + { "dr6", DREG, 6 }, | |
1271 | + { "dr7", DREG, 7 }, | |
1272 | + { "dr8", DREG, 8 }, | |
1273 | + { "dr9", DREG, 9 }, | |
1274 | + { "dr10", DREG, 10 }, | |
1275 | + { "dr11", DREG, 11 }, | |
1276 | + { "dr12", DREG, 12 }, | |
1277 | + { "dr13", DREG, 13 }, | |
1278 | + { "dr14", DREG, 14 }, | |
1279 | + { "dr15", DREG, 15 }, | |
1280 | + | |
1281 | + { "drh0", DREGH, 0 }, | |
1282 | + { "drh1", DREGH, 1 }, | |
1283 | + { "drh2", DREGH, 2 }, | |
1284 | + { "drh3", DREGH, 3 }, | |
1285 | + { "drh4", DREGH, 4 }, | |
1286 | + { "drh5", DREGH, 5 }, | |
1287 | + { "drh6", DREGH, 6 }, | |
1288 | + { "drh7", DREGH, 7 }, | |
1289 | + { "drh8", DREGH, 8 }, | |
1290 | + { "drh9", DREGH, 9 }, | |
1291 | + { "drh10", DREGH, 10 }, | |
1292 | + { "drh11", DREGH, 11 }, | |
1293 | + { "drh12", DREGH, 12 }, | |
1294 | + { "drh13", DREGH, 13 }, | |
1295 | + { "drh14", DREGH, 14 }, | |
1296 | + { "drh15", DREGH, 15 }, | |
1297 | + | |
1298 | + { "drl0", DREGL, 0 }, | |
1299 | + { "drl1", DREGL, 1 }, | |
1300 | + { "drl2", DREGL, 2 }, | |
1301 | + { "drl3", DREGL, 3 }, | |
1302 | + { "drl4", DREGL, 4 }, | |
1303 | + { "drl5", DREGL, 5 }, | |
1304 | + { "drl6", DREGL, 6 }, | |
1305 | + { "drl7", DREGL, 7 }, | |
1306 | + { "drl8", DREGL, 8 }, | |
1307 | + { "drl9", DREGL, 9 }, | |
1308 | + { "drl10", DREGL, 10 }, | |
1309 | + { "drl11", DREGL, 11 }, | |
1310 | + { "drl12", DREGL, 12 }, | |
1311 | + { "drl13", DREGL, 13 }, | |
1312 | + { "drl14", DREGL, 14 }, | |
1313 | + { "drl15", DREGL, 15 }, | |
1314 | + | |
1315 | + { "DPSW", DCREG, 0 }, | |
1316 | + { "DCMR", DCREG, 1 }, | |
1317 | + { "DCENT", DCREG, 2 }, | |
1318 | + { "DEPC", DCREG, 3 }, | |
1319 | + { "DCR0", DCREG, 0 }, | |
1320 | + { "DCR1", DCREG, 1 }, | |
1321 | + { "DCR2", DCREG, 2 }, | |
1322 | + { "DCR3", DCREG, 3 }, | |
1323 | + | |
1138 | 1324 | { ".s", DOT_S, 0 }, |
1139 | 1325 | { ".b", DOT_B, 0 }, |
1140 | 1326 | { ".w", DOT_W, 0 }, |
@@ -1142,6 +1328,7 @@ token_table[] = | ||
1142 | 1328 | { ".a", DOT_A , 0}, |
1143 | 1329 | { ".ub", DOT_UB, 0 }, |
1144 | 1330 | { ".uw", DOT_UW , 0}, |
1331 | + { ".d", DOT_D , 0}, | |
1145 | 1332 | |
1146 | 1333 | { "c", FLAG, 0 }, |
1147 | 1334 | { "z", FLAG, 1 }, |
@@ -1160,6 +1347,8 @@ token_table[] = | ||
1160 | 1347 | { "and", AND_, IS_OPCODE }, |
1161 | 1348 | OPC(BCLR), |
1162 | 1349 | OPC(BCND), |
1350 | + OPC(BFMOV), | |
1351 | + OPC(BFMOVZ), | |
1163 | 1352 | OPC(BMCND), |
1164 | 1353 | OPC(BNOT), |
1165 | 1354 | OPC(BRA), |
@@ -1169,9 +1358,23 @@ token_table[] = | ||
1169 | 1358 | OPC(BTST), |
1170 | 1359 | OPC(CLRPSW), |
1171 | 1360 | OPC(CMP), |
1361 | + OPC(DABS), | |
1362 | + OPC(DADD), | |
1172 | 1363 | OPC(DBT), |
1364 | + OPC(DDIV), | |
1173 | 1365 | OPC(DIV), |
1174 | 1366 | OPC(DIVU), |
1367 | + OPC(DMOV), | |
1368 | + OPC(DMUL), | |
1369 | + OPC(DNEG), | |
1370 | + OPC(DPOPM), | |
1371 | + OPC(DPUSHM), | |
1372 | + OPC(DROUND), | |
1373 | + OPC(DSQRT), | |
1374 | + OPC(DSUB), | |
1375 | + OPC(DTOF), | |
1376 | + OPC(DTOI), | |
1377 | + OPC(DTOU), | |
1175 | 1378 | OPC(EDIV), |
1176 | 1379 | OPC(EDIVU), |
1177 | 1380 | OPC(EMACA), |
@@ -1185,10 +1388,12 @@ token_table[] = | ||
1185 | 1388 | OPC(FMUL), |
1186 | 1389 | OPC(FREIT), |
1187 | 1390 | OPC(FSQRT), |
1391 | + OPC(FTOD), | |
1188 | 1392 | OPC(FTOU), |
1189 | 1393 | OPC(FSUB), |
1190 | 1394 | OPC(FTOI), |
1191 | 1395 | OPC(INT), |
1396 | + OPC(ITOD), | |
1192 | 1397 | OPC(ITOF), |
1193 | 1398 | OPC(JMP), |
1194 | 1399 | OPC(JSR), |
@@ -1197,6 +1402,9 @@ token_table[] = | ||
1197 | 1402 | OPC(MVFACMI), |
1198 | 1403 | OPC(MVFACLO), |
1199 | 1404 | OPC(MVFC), |
1405 | + OPC(MVFDC), | |
1406 | + OPC(MVFDR), | |
1407 | + OPC(MVTDC), | |
1200 | 1408 | OPC(MVTACGU), |
1201 | 1409 | OPC(MVTACHI), |
1202 | 1410 | OPC(MVTACLO), |
@@ -1243,12 +1451,14 @@ token_table[] = | ||
1243 | 1451 | OPC(ROTL), |
1244 | 1452 | OPC(ROTR), |
1245 | 1453 | OPC(ROUND), |
1454 | + OPC(RSTR), | |
1246 | 1455 | OPC(RTE), |
1247 | 1456 | OPC(RTFI), |
1248 | 1457 | OPC(RTS), |
1249 | 1458 | OPC(RTSD), |
1250 | 1459 | OPC(SAT), |
1251 | 1460 | OPC(SATR), |
1461 | + OPC(SAVE), | |
1252 | 1462 | OPC(SBB), |
1253 | 1463 | OPC(SCCND), |
1254 | 1464 | OPC(SCMPU), |
@@ -1267,6 +1477,7 @@ token_table[] = | ||
1267 | 1477 | OPC(SUNTIL), |
1268 | 1478 | OPC(SWHILE), |
1269 | 1479 | OPC(TST), |
1480 | + OPC(UTOD), | |
1270 | 1481 | OPC(UTOF), |
1271 | 1482 | OPC(WAIT), |
1272 | 1483 | OPC(XCHG), |
@@ -1289,12 +1500,13 @@ condition_opcode_table[] = | ||
1289 | 1500 | |
1290 | 1501 | #define NUM_CONDITION_OPCODES (sizeof (condition_opcode_table) / sizeof (condition_opcode_table[0])) |
1291 | 1502 | |
1292 | -static struct | |
1503 | +struct condition_symbol | |
1293 | 1504 | { |
1294 | 1505 | const char * string; |
1295 | 1506 | int val; |
1296 | -} | |
1297 | -condition_table[] = | |
1507 | +}; | |
1508 | + | |
1509 | +static struct condition_symbol condition_table[] = | |
1298 | 1510 | { |
1299 | 1511 | { "z", 0 }, |
1300 | 1512 | { "eq", 0 }, |
@@ -1314,11 +1526,20 @@ condition_table[] = | ||
1314 | 1526 | { "n", 7 }, |
1315 | 1527 | { "lt", 9 }, |
1316 | 1528 | { "le", 11 }, |
1317 | - { "no", 13 } | |
1529 | + { "no", 13 }, | |
1318 | 1530 | /* never = 15 */ |
1319 | 1531 | }; |
1320 | 1532 | |
1533 | +static struct condition_symbol double_condition_table[] = | |
1534 | +{ | |
1535 | + { "un", 1 }, | |
1536 | + { "eq", 2 }, | |
1537 | + { "lt", 4 }, | |
1538 | + { "le", 6 }, | |
1539 | +}; | |
1540 | + | |
1321 | 1541 | #define NUM_CONDITIONS (sizeof (condition_table) / sizeof (condition_table[0])) |
1542 | +#define NUM_DOUBLE_CONDITIONS (sizeof (double_condition_table) / sizeof (double_condition_table[0])) | |
1322 | 1543 | |
1323 | 1544 | void |
1324 | 1545 | rx_lex_init (char * beginning, char * ending) |
@@ -1333,7 +1554,7 @@ rx_lex_init (char * beginning, char * ending) | ||
1333 | 1554 | } |
1334 | 1555 | |
1335 | 1556 | static int |
1336 | -check_condition (const char * base) | |
1557 | +check_condition (const char * base, struct condition_symbol *t, unsigned int num) | |
1337 | 1558 | { |
1338 | 1559 | char * cp; |
1339 | 1560 | unsigned int i; |
@@ -1343,11 +1564,11 @@ check_condition (const char * base) | ||
1343 | 1564 | if (memcmp (rx_lex_start, base, strlen (base))) |
1344 | 1565 | return 0; |
1345 | 1566 | cp = rx_lex_start + strlen (base); |
1346 | - for (i = 0; i < NUM_CONDITIONS; i ++) | |
1567 | + for (i = 0; i < num; i ++) | |
1347 | 1568 | { |
1348 | - if (strcasecmp (cp, condition_table[i].string) == 0) | |
1569 | + if (strcasecmp (cp, t[i].string) == 0) | |
1349 | 1570 | { |
1350 | - rx_lval.regno = condition_table[i].val; | |
1571 | + rx_lval.regno = t[i].val; | |
1351 | 1572 | return 1; |
1352 | 1573 | } |
1353 | 1574 | } |
@@ -1408,14 +1629,25 @@ rx_lex (void) | ||
1408 | 1629 | } |
1409 | 1630 | |
1410 | 1631 | if (rx_last_token == 0) |
1411 | - for (ci = 0; ci < NUM_CONDITION_OPCODES; ci ++) | |
1412 | - if (check_condition (condition_opcode_table[ci].string)) | |
1632 | + { | |
1633 | + for (ci = 0; ci < NUM_CONDITION_OPCODES; ci ++) | |
1634 | + if (check_condition (condition_opcode_table[ci].string, | |
1635 | + condition_table, NUM_CONDITIONS)) | |
1636 | + { | |
1637 | + *e = save; | |
1638 | + rx_lex_start = e; | |
1639 | + rx_last_token = condition_opcode_table[ci].token; | |
1640 | + return condition_opcode_table[ci].token; | |
1641 | + } | |
1642 | + if (check_condition ("dcmp", double_condition_table, | |
1643 | + NUM_DOUBLE_CONDITIONS)) | |
1413 | 1644 | { |
1414 | 1645 | *e = save; |
1415 | 1646 | rx_lex_start = e; |
1416 | - rx_last_token = condition_opcode_table[ci].token; | |
1417 | - return condition_opcode_table[ci].token; | |
1647 | + rx_last_token = DCMP; | |
1648 | + return DCMP; | |
1418 | 1649 | } |
1650 | + } | |
1419 | 1651 | |
1420 | 1652 | for (i = 0; i < NUM_TOKENS; i++) |
1421 | 1653 | if (strcasecmp (rx_lex_start, token_table[i].string) == 0 |
@@ -1446,7 +1678,7 @@ rx_lex (void) | ||
1446 | 1678 | rx_in_brackets = 0; |
1447 | 1679 | |
1448 | 1680 | if (rx_in_brackets |
1449 | - || rx_last_token == REG | |
1681 | + || rx_last_token == REG || rx_last_token == DREG || rx_last_token == DCREG | |
1450 | 1682 | || strchr ("[],#", *rx_lex_start)) |
1451 | 1683 | { |
1452 | 1684 | rx_last_token = *rx_lex_start; |
@@ -1679,7 +1911,7 @@ immediate (expressionS exp, int type, int pos, int bits) | ||
1679 | 1911 | rx_op (exp, 4, type); |
1680 | 1912 | return 0; |
1681 | 1913 | } |
1682 | - else if (type == RXREL_SIGNED) | |
1914 | + else if (type == RXREL_SIGNED && pos >= 0) | |
1683 | 1915 | { |
1684 | 1916 | /* This is a symbolic immediate, we will relax it later. */ |
1685 | 1917 | rx_relax (RX_RELAX_IMM, pos); |
@@ -1754,6 +1986,11 @@ displacement (expressionS exp, int msize) | ||
1754 | 1986 | rx_error (_("long displacement not long-aligned")); |
1755 | 1987 | vshift = 2; |
1756 | 1988 | break; |
1989 | + case DSIZE: | |
1990 | + if (val & 7) | |
1991 | + rx_error (_("double displacement not double-aligned")); | |
1992 | + vshift = 3; | |
1993 | + break; | |
1757 | 1994 | default: |
1758 | 1995 | as_bad (_("displacement with unknown size (internal bug?)\n")); |
1759 | 1996 | break; |
@@ -1828,3 +2065,10 @@ rx_check_v2 (void) | ||
1828 | 2065 | if (rx_cpu < RXV2) |
1829 | 2066 | rx_error (_("target CPU type does not support v2 instructions")); |
1830 | 2067 | } |
2068 | + | |
2069 | +static void | |
2070 | +rx_check_v3 (void) | |
2071 | +{ | |
2072 | + if (rx_cpu < RXV3) | |
2073 | + rx_error (_("target CPU type does not support v3 instructions")); | |
2074 | +} |
@@ -44,7 +44,11 @@ const char FLT_CHARS[] = "dD"; | ||
44 | 44 | /* ELF flags to set in the output file header. */ |
45 | 45 | static int elf_flags = E_FLAG_RX_ABI; |
46 | 46 | |
47 | +#ifndef TE_LINUX | |
47 | 48 | bfd_boolean rx_use_conventional_section_names = FALSE; |
49 | +#else | |
50 | +bfd_boolean rx_use_conventional_section_names = TRUE; | |
51 | +#endif | |
48 | 52 | static bfd_boolean rx_use_small_data_limit = FALSE; |
49 | 53 | |
50 | 54 | static bfd_boolean rx_pid_mode = FALSE; |
@@ -108,15 +112,17 @@ struct cpu_type | ||
108 | 112 | { |
109 | 113 | const char *cpu_name; |
110 | 114 | enum rx_cpu_types type; |
115 | + int flag; | |
111 | 116 | }; |
112 | 117 | |
113 | 118 | struct cpu_type cpu_type_list[] = |
114 | 119 | { |
115 | - {"rx100",RX100}, | |
116 | - {"rx200",RX200}, | |
117 | - {"rx600",RX600}, | |
118 | - {"rx610",RX610}, | |
119 | - {"rxv2",RXV2} | |
120 | + {"rx100", RX100, 0}, | |
121 | + {"rx200", RX200, 0}, | |
122 | + {"rx600", RX600, 0}, | |
123 | + {"rx610", RX610, 0}, | |
124 | + {"rxv2", RXV2, E_FLAG_RX_V2}, | |
125 | + {"rxv3", RXV3, E_FLAG_RX_V3}, | |
120 | 126 | }; |
121 | 127 | |
122 | 128 | int |
@@ -181,8 +187,7 @@ md_parse_option (int c ATTRIBUTE_UNUSED, const char * arg ATTRIBUTE_UNUSED) | ||
181 | 187 | if (strcasecmp (arg, cpu_type_list[i].cpu_name) == 0) |
182 | 188 | { |
183 | 189 | rx_cpu = cpu_type_list[i].type; |
184 | - if (rx_cpu == RXV2) | |
185 | - elf_flags |= E_FLAG_RX_V2; | |
190 | + elf_flags |= cpu_type_list[i].flag; | |
186 | 191 | return 1; |
187 | 192 | } |
188 | 193 | } |
@@ -212,7 +217,7 @@ md_show_usage (FILE * stream) | ||
212 | 217 | fprintf (stream, _(" --mrelax\n")); |
213 | 218 | fprintf (stream, _(" --mpid\n")); |
214 | 219 | fprintf (stream, _(" --mint-register=<value>\n")); |
215 | - fprintf (stream, _(" --mcpu=<rx100|rx200|rx600|rx610|rxv2>\n")); | |
220 | + fprintf (stream, _(" --mcpu=<rx100|rx200|rx600|rx610|rxv2|rxv3>\n")); | |
216 | 221 | fprintf (stream, _(" --mno-allow-string-insns")); |
217 | 222 | } |
218 | 223 |
@@ -723,6 +728,8 @@ typedef struct rx_bytesT | ||
723 | 728 | fixS * fixP; |
724 | 729 | } fixups[2]; |
725 | 730 | int n_fixups; |
731 | + char post[1]; | |
732 | + int n_post; | |
726 | 733 | struct |
727 | 734 | { |
728 | 735 | char type; |
@@ -947,6 +954,20 @@ rx_field5s2 (expressionS exp) | ||
947 | 954 | rx_bytes.base[1] |= (val ) & 0x0f; |
948 | 955 | } |
949 | 956 | |
957 | +void | |
958 | +rx_bfield(expressionS s, expressionS d, expressionS w) | |
959 | +{ | |
960 | + int slsb = s.X_add_number; | |
961 | + int dlsb = d.X_add_number; | |
962 | + int width = w.X_add_number; | |
963 | + unsigned int imm = | |
964 | + (((dlsb + width) & 0x1f) << 10 | (dlsb << 5) | | |
965 | + ((dlsb - slsb) & 0x1f)); | |
966 | + rx_bytes.ops[0] = imm & 0xff; | |
967 | + rx_bytes.ops[1] = (imm >> 8); | |
968 | + rx_bytes.n_ops = 2; | |
969 | +} | |
970 | + | |
950 | 971 | #define OP(x) rx_bytes.ops[rx_bytes.n_ops++] = (x) |
951 | 972 | |
952 | 973 | #define F_PRECISION 2 |
@@ -1008,6 +1029,11 @@ rx_op (expressionS exp, int nbytes, int type) | ||
1008 | 1029 | } |
1009 | 1030 | } |
1010 | 1031 | |
1032 | +void rx_post(char byte) | |
1033 | +{ | |
1034 | + rx_bytes.post[rx_bytes.n_post++] = byte; | |
1035 | +} | |
1036 | + | |
1011 | 1037 | int |
1012 | 1038 | rx_wrap (void) |
1013 | 1039 | { |
@@ -1133,21 +1159,22 @@ md_assemble (char * str) | ||
1133 | 1159 | 0 /* offset */, |
1134 | 1160 | 0 /* opcode */); |
1135 | 1161 | frag_then->fr_opcode = bytes; |
1136 | - frag_then->fr_fix += rx_bytes.n_base + rx_bytes.n_ops; | |
1137 | - frag_then->fr_subtype = rx_bytes.n_base + rx_bytes.n_ops; | |
1162 | + frag_then->fr_fix += rx_bytes.n_base + rx_bytes.n_ops + rx_bytes.n_post; | |
1163 | + frag_then->fr_subtype = rx_bytes.n_base + rx_bytes.n_ops + rx_bytes.n_post; | |
1138 | 1164 | } |
1139 | 1165 | else |
1140 | 1166 | { |
1141 | - bytes = frag_more (rx_bytes.n_base + rx_bytes.n_ops); | |
1167 | + bytes = frag_more (rx_bytes.n_base + rx_bytes.n_ops + rx_bytes.n_post); | |
1142 | 1168 | frag_then = frag_now; |
1143 | 1169 | if (fetchalign_bytes) |
1144 | - fetchalign_bytes->n_ops = rx_bytes.n_base + rx_bytes.n_ops; | |
1170 | + fetchalign_bytes->n_ops = rx_bytes.n_base + rx_bytes.n_ops + rx_bytes.n_post; | |
1145 | 1171 | } |
1146 | 1172 | |
1147 | 1173 | fetchalign_bytes = NULL; |
1148 | 1174 | |
1149 | 1175 | APPEND (base, n_base); |
1150 | 1176 | APPEND (ops, n_ops); |
1177 | + APPEND (post, n_post); | |
1151 | 1178 | |
1152 | 1179 | if (rx_bytes.link_relax && rx_bytes.n_fixups) |
1153 | 1180 | { |
@@ -1196,7 +1223,6 @@ md_assemble (char * str) | ||
1196 | 1223 | if (frag_then->tc_frag_data) |
1197 | 1224 | frag_then->tc_frag_data->fixups[i].fixP = f; |
1198 | 1225 | } |
1199 | - | |
1200 | 1226 | dwarf2_emit_insn (idx); |
1201 | 1227 | } |
1202 | 1228 |
@@ -111,7 +111,7 @@ START_RELOC_NUMBERS (elf_rx_reloc_type) | ||
111 | 111 | END_RELOC_NUMBERS (R_RX_max) |
112 | 112 | |
113 | 113 | #define EF_RX_CPU_RX 0x00000079 /* FIXME: this collides with the E_FLAG_RX_... values below. */ |
114 | -#define EF_RX_CPU_MASK 0x0000007F /* specific cpu bits. */ | |
114 | +#define EF_RX_CPU_MASK 0x000003FF /* specific cpu bits. */ | |
115 | 115 | #define EF_RX_ALL_FLAGS (EF_RX_CPU_MASK) |
116 | 116 | |
117 | 117 | /* Values for the e_flags field in the ELF header. */ |
@@ -124,6 +124,7 @@ END_RELOC_NUMBERS (R_RX_max) | ||
124 | 124 | #define E_FLAG_RX_SINSNS_NO 0 /* Bit-5 if this binary must not be linked with a string instruction using binary. */ |
125 | 125 | #define E_FLAG_RX_SINSNS_MASK (3 << 6) /* Mask of bits used to determine string instruction use. */ |
126 | 126 | #define E_FLAG_RX_V2 (1 << 8) /* RX v2 instructions */ |
127 | +#define E_FLAG_RX_V3 (1 << 9) /* RX v3 instructions */ | |
127 | 128 | |
128 | 129 | /* These define the addend field of R_RX_RH_RELAX relocations. */ |
129 | 130 | #define RX_RELAXA_IMM6 0x00000010 /* Imm8/16/24/32 at bit offset 6. */ |