diff options
author | Denis Chertykov <denisc@overta.ru> | 2000-06-07 17:42:44 +0000 |
---|---|---|
committer | Denis Chertykov <denisc@overta.ru> | 2000-06-07 17:42:44 +0000 |
commit | 1188e08253eaa931d9f174332f5750471cd43c62 (patch) | |
tree | ff3807043560c305fb09063ff6374985dc1d03c9 /gas/config/tc-avr.c | |
parent | 2532761bdf915384fa6c2485020fad1c3f24cefe (diff) | |
download | gdb-1188e08253eaa931d9f174332f5750471cd43c62.zip gdb-1188e08253eaa931d9f174332f5750471cd43c62.tar.gz gdb-1188e08253eaa931d9f174332f5750471cd43c62.tar.bz2 |
* config/tc-avr.c (AVR_ISA_???): moved to include/opcode/avr.h
(REGISTER_P): likewise.
(avr_opcodes): uses include/opcode/avr.h
(avr_operand): enable ld r,Z or st r,Z for at90s1200.
Diffstat (limited to 'gas/config/tc-avr.c')
-rw-r--r-- | gas/config/tc-avr.c | 243 |
1 files changed, 28 insertions, 215 deletions
diff --git a/gas/config/tc-avr.c b/gas/config/tc-avr.c index 98a69a2..8b32d7c 100644 --- a/gas/config/tc-avr.c +++ b/gas/config/tc-avr.c @@ -25,33 +25,29 @@ #include "as.h" #include "subsegs.h" +struct avr_opcodes_s +{ + char *name; + char *constraints; + int insn_size; /* in words */ + int isa; + unsigned int bin_opcode; +}; + +#define AVR_INSN(NAME, CONSTR, OPCODE, SIZE, ISA, BIN) \ +{#NAME, CONSTR, SIZE, ISA, BIN}, + +struct avr_opcodes_s avr_opcodes[] = +{ + #include "opcode/avr.h" + {NULL, NULL, 0, 0, 0} +}; + + const char comment_chars[] = ";"; const char line_comment_chars[] = "#"; const char line_separator_chars[] = "$"; -#define AVR_ISA_1200 0x0001 /* in the beginning there was ... */ -#define AVR_ISA_LPM 0x0002 /* device has LPM */ -#define AVR_ISA_LPMX 0x0004 /* device has LPM Rd,Z[+] */ -#define AVR_ISA_SRAM 0x0008 /* device has SRAM (LD, ST, PUSH, POP, ...) */ -#define AVR_ISA_WRAP 0x0010 /* device has exactly 8K program memory */ -#define AVR_ISA_MEGA 0x0020 /* device has >8K program memory (JMP, CALL) */ -#define AVR_ISA_MUL 0x0040 /* device has new core (MUL, MOVW, ...) */ -#define AVR_ISA_ELPM 0x0080 /* device has >64K program memory (ELPM) */ -#define AVR_ISA_ELPMX 0x0100 /* device has ELPM Rd,Z[+] (none yet) */ -#define AVR_ISA_SPM 0x0200 /* device can program itself (<=64K) */ -#define AVR_ISA_ESPM 0x0400 /* device can program itself (>64K, none yet) */ -#define AVR_ISA_EIND 0x0800 /* device has >128K program memory (none yet) */ - -#define AVR_ISA_TINY1 (AVR_ISA_1200 | AVR_ISA_LPM) -#define AVR_ISA_2xxx (AVR_ISA_TINY1 | AVR_ISA_SRAM) -#define AVR_ISA_85xx (AVR_ISA_2xxx | AVR_ISA_WRAP) -#define AVR_ISA_M603 (AVR_ISA_2xxx | AVR_ISA_MEGA) -#define AVR_ISA_M103 (AVR_ISA_M603 | AVR_ISA_ELPM) -#define AVR_ISA_M161 (AVR_ISA_M603 | AVR_ISA_MUL | AVR_ISA_LPMX | AVR_ISA_SPM) -#define AVR_ISA_94K (AVR_ISA_M603 | AVR_ISA_MUL | AVR_ISA_LPMX) - -#define AVR_ISA_ALL 0xFFFF - const char *md_shortopts = "m:"; struct mcu_type_s { @@ -109,21 +105,6 @@ const pseudo_typeS md_pseudo_table[] = }; #define LDI_IMMEDIATE(x) (((x) & 0xf) | (((x) << 4) & 0xf00)) -#define REGISTER_P(x) ((x) == 'r' \ - || (x) == 'd' \ - || (x) == 'w' \ - || (x) == 'a' \ - || (x) == 'v') - -struct avr_opcodes_s -{ - char *name; - char *constraints; - char *opcode; - int insn_size; /* in words */ - int isa; - unsigned int bin_opcode; -}; static char * skip_space (char * s); static char * extract_word (char *from, char *to, int limit); @@ -136,170 +117,6 @@ static bfd_reloc_code_real_type avr_ldi_expression (expressionS *exp); long md_pcrel_from_section PARAMS ((fixS *, segT)); -/* constraint letters - r - any register - d - `ldi' register (r16-r31) - v - `movw' even register (r0, r2, ..., r28, r30) - a - `fmul' register (r16-r23) - w - `adiw' register (r24,r26,r28,r30) - e - pointer registers (X,Y,Z) - b - base pointer register and displacement ([YZ]+disp) - z - Z pointer register (for [e]lpm Rd,Z[+]) - M - immediate value from 0 to 255 - n - immediate value from 0 to 255 ( n = ~M ). Relocation impossible - s - immediate value from 0 to 7 - P - Port address value from 0 to 64. (in, out) - p - Port address value from 0 to 32. (cbi, sbi, sbic, sbis) - K - immediate value from 0 to 64 (used in `adiw', `sbiw') - i - immediate value - l - signed pc relative offset from -64 to 63 - L - signed pc relative offset from -2048 to 2047 - h - absolut code address (call, jmp) - S - immediate value from 0 to 7 (S = s << 4) -*/ - -struct avr_opcodes_s avr_opcodes[] = -{ - {"adc", "r,r", "000111rdddddrrrr", 1, AVR_ISA_1200, 0x1c00}, - {"add", "r,r", "000011rdddddrrrr", 1, AVR_ISA_1200, 0x0c00}, - {"and", "r,r", "001000rdddddrrrr", 1, AVR_ISA_1200, 0x2000}, - {"cp", "r,r", "000101rdddddrrrr", 1, AVR_ISA_1200, 0x1400}, - {"cpc", "r,r", "000001rdddddrrrr", 1, AVR_ISA_1200, 0x0400}, - {"cpse", "r,r", "000100rdddddrrrr", 1, AVR_ISA_1200, 0x1000}, - {"eor", "r,r", "001001rdddddrrrr", 1, AVR_ISA_1200, 0x2400}, - {"mov", "r,r", "001011rdddddrrrr", 1, AVR_ISA_1200, 0x2c00}, - {"mul", "r,r", "100111rdddddrrrr", 1, AVR_ISA_MUL, 0x9c00}, - {"or", "r,r", "001010rdddddrrrr", 1, AVR_ISA_1200, 0x2800}, - {"sbc", "r,r", "000010rdddddrrrr", 1, AVR_ISA_1200, 0x0800}, - {"sub", "r,r", "000110rdddddrrrr", 1, AVR_ISA_1200, 0x1800}, - - {"clr", "r=r", "001001rdddddrrrr", 1, AVR_ISA_1200, 0x2400}, - {"lsl", "r=r", "000011rdddddrrrr", 1, AVR_ISA_1200, 0x0c00}, - {"rol", "r=r", "000111rdddddrrrr", 1, AVR_ISA_1200, 0x1c00}, - {"tst", "r=r", "001000rdddddrrrr", 1, AVR_ISA_1200, 0x2000}, - - {"andi", "d,M", "0111KKKKddddKKKK", 1, AVR_ISA_1200, 0x7000}, - /*XXX special case*/ - {"cbr", "d,n", "0111KKKKddddKKKK", 1, AVR_ISA_1200, 0x7000}, - {"cpi", "d,M", "0011KKKKddddKKKK", 1, AVR_ISA_1200, 0x3000}, - {"ldi", "d,M", "1110KKKKddddKKKK", 1, AVR_ISA_1200, 0xe000}, - {"ori", "d,M", "0110KKKKddddKKKK", 1, AVR_ISA_1200, 0x6000}, - {"sbci", "d,M", "0100KKKKddddKKKK", 1, AVR_ISA_1200, 0x4000}, - {"sbr", "d,M", "0110KKKKddddKKKK", 1, AVR_ISA_1200, 0x6000}, - {"subi", "d,M", "0101KKKKddddKKKK", 1, AVR_ISA_1200, 0x5000}, - - {"sbrc", "r,s", "1111110rrrrr0sss", 1, AVR_ISA_1200, 0xfc00}, - {"sbrs", "r,s", "1111111rrrrr0sss", 1, AVR_ISA_1200, 0xfe00}, - {"bld", "r,s", "1111100ddddd0sss", 1, AVR_ISA_1200, 0xf800}, - {"bst", "r,s", "1111101ddddd0sss", 1, AVR_ISA_1200, 0xfa00}, - - {"in", "r,P", "10110PPdddddPPPP", 1, AVR_ISA_1200, 0xb000}, - {"out", "P,r", "10111PPrrrrrPPPP", 1, AVR_ISA_1200, 0xb800}, - - {"adiw", "w,K", "10010110KKddKKKK", 1, AVR_ISA_2xxx, 0x9600}, - {"sbiw", "w,K", "10010111KKddKKKK", 1, AVR_ISA_2xxx, 0x9700}, - - {"cbi", "p,s", "10011000pppppsss", 1, AVR_ISA_1200, 0x9800}, - {"sbi", "p,s", "10011010pppppsss", 1, AVR_ISA_1200, 0x9a00}, - {"sbic", "p,s", "10011001pppppsss", 1, AVR_ISA_1200, 0x9900}, - {"sbis", "p,s", "10011011pppppsss", 1, AVR_ISA_1200, 0x9b00}, - - /* ee = {X=11,Y=10,Z=00, 0} */ - {"ld", "r,e", "100!000dddddee-+", 1, AVR_ISA_2xxx, 0x8000}, - {"st", "e,r", "100!001rrrrree-+", 1, AVR_ISA_2xxx, 0x8200}, - {"ldd", "r,b", "10o0oo0dddddbooo", 1, AVR_ISA_2xxx, 0x8000}, - {"std", "b,r", "10o0oo1rrrrrbooo", 1, AVR_ISA_2xxx, 0x8200}, - {"sts", "i,r", "1001001ddddd0000", 2, AVR_ISA_2xxx, 0x9200}, - {"lds", "r,i", "1001000ddddd0000", 2, AVR_ISA_2xxx, 0x9000}, - - {"brbc", "s,l", "111101lllllllsss", 1, AVR_ISA_1200, 0xf400}, - {"brbs", "s,l", "111100lllllllsss", 1, AVR_ISA_1200, 0xf000}, - - {"brcc", "l", "111101lllllll000", 1, AVR_ISA_1200, 0xf400}, - {"brcs", "l", "111100lllllll000", 1, AVR_ISA_1200, 0xf000}, - {"breq", "l", "111100lllllll001", 1, AVR_ISA_1200, 0xf001}, - {"brge", "l", "111101lllllll100", 1, AVR_ISA_1200, 0xf404}, - {"brhc", "l", "111101lllllll101", 1, AVR_ISA_1200, 0xf405}, - {"brhs", "l", "111100lllllll101", 1, AVR_ISA_1200, 0xf005}, - {"brid", "l", "111101lllllll111", 1, AVR_ISA_1200, 0xf407}, - {"brie", "l", "111100lllllll111", 1, AVR_ISA_1200, 0xf007}, - {"brlo", "l", "111100lllllll000", 1, AVR_ISA_1200, 0xf000}, - {"brlt", "l", "111100lllllll100", 1, AVR_ISA_1200, 0xf004}, - {"brmi", "l", "111100lllllll010", 1, AVR_ISA_1200, 0xf002}, - {"brne", "l", "111101lllllll001", 1, AVR_ISA_1200, 0xf401}, - {"brpl", "l", "111101lllllll010", 1, AVR_ISA_1200, 0xf402}, - {"brsh", "l", "111101lllllll000", 1, AVR_ISA_1200, 0xf400}, - {"brtc", "l", "111101lllllll110", 1, AVR_ISA_1200, 0xf406}, - {"brts", "l", "111100lllllll110", 1, AVR_ISA_1200, 0xf006}, - {"brvc", "l", "111101lllllll011", 1, AVR_ISA_1200, 0xf403}, - {"brvs", "l", "111100lllllll011", 1, AVR_ISA_1200, 0xf003}, - - {"rcall", "L", "1101LLLLLLLLLLLL", 1, AVR_ISA_1200, 0xd000}, - {"rjmp", "L", "1100LLLLLLLLLLLL", 1, AVR_ISA_1200, 0xc000}, - - {"call", "h", "1001010hhhhh111h", 2, AVR_ISA_MEGA, 0x940e}, - {"jmp", "h", "1001010hhhhh110h", 2, AVR_ISA_MEGA, 0x940c}, - - {"asr", "r", "1001010rrrrr0101", 1, AVR_ISA_1200, 0x9405}, - {"com", "r", "1001010rrrrr0000", 1, AVR_ISA_1200, 0x9400}, - {"dec", "r", "1001010rrrrr1010", 1, AVR_ISA_1200, 0x940a}, - {"inc", "r", "1001010rrrrr0011", 1, AVR_ISA_1200, 0x9403}, - {"lsr", "r", "1001010rrrrr0110", 1, AVR_ISA_1200, 0x9406}, - {"neg", "r", "1001010rrrrr0001", 1, AVR_ISA_1200, 0x9401}, - {"pop", "r", "1001000rrrrr1111", 1, AVR_ISA_2xxx, 0x900f}, - {"push", "r", "1001001rrrrr1111", 1, AVR_ISA_2xxx, 0x920f}, - {"ror", "r", "1001010rrrrr0111", 1, AVR_ISA_1200, 0x9407}, - {"ser", "d", "11101111dddd1111", 1, AVR_ISA_1200, 0xef0f}, - {"swap", "r", "1001010rrrrr0010", 1, AVR_ISA_1200, 0x9402}, - - {"bclr", "S", "100101001SSS1000", 1, AVR_ISA_1200, 0x9488}, - {"bset", "S", "100101000SSS1000", 1, AVR_ISA_1200, 0x9408}, - - {"clc", "", "1001010010001000", 1, AVR_ISA_1200, 0x9488}, - {"clh", "", "1001010011011000", 1, AVR_ISA_1200, 0x94d8}, - {"cli", "", "1001010011111000", 1, AVR_ISA_1200, 0x94f8}, - {"cln", "", "1001010010101000", 1, AVR_ISA_1200, 0x94a8}, - {"cls", "", "1001010011001000", 1, AVR_ISA_1200, 0x94c8}, - {"clt", "", "1001010011101000", 1, AVR_ISA_1200, 0x94e8}, - {"clv", "", "1001010010111000", 1, AVR_ISA_1200, 0x94b8}, - {"clz", "", "1001010010011000", 1, AVR_ISA_1200, 0x9498}, - {"icall","", "1001010100001001", 1, AVR_ISA_2xxx, 0x9509}, - {"ijmp", "", "1001010000001001", 1, AVR_ISA_2xxx, 0x9409}, - {"lpm", "", "1001010111001000", 1, AVR_ISA_TINY1,0x95c8}, - {"nop", "", "0000000000000000", 1, AVR_ISA_1200, 0x0000}, - {"ret", "", "1001010100001000", 1, AVR_ISA_1200, 0x9508}, - {"reti", "", "1001010100011000", 1, AVR_ISA_1200, 0x9518}, - {"sec", "", "1001010000001000", 1, AVR_ISA_1200, 0x9408}, - {"seh", "", "1001010001011000", 1, AVR_ISA_1200, 0x9458}, - {"sei", "", "1001010001111000", 1, AVR_ISA_1200, 0x9478}, - {"sen", "", "1001010000101000", 1, AVR_ISA_1200, 0x9428}, - {"ses", "", "1001010001001000", 1, AVR_ISA_1200, 0x9448}, - {"set", "", "1001010001101000", 1, AVR_ISA_1200, 0x9468}, - {"sev", "", "1001010000111000", 1, AVR_ISA_1200, 0x9438}, - {"sez", "", "1001010000011000", 1, AVR_ISA_1200, 0x9418}, - {"sleep","", "1001010110001000", 1, AVR_ISA_1200, 0x9588}, - {"wdr", "", "1001010110101000", 1, AVR_ISA_1200, 0x95a8}, - {"elpm", "", "1001010111011000", 1, AVR_ISA_ELPM, 0x95d8}, - {"spm", "", "1001010111101000", 1, AVR_ISA_SPM, 0x95e8}, - {"movw", "v,v", "00000001ddddrrrr", 1, AVR_ISA_MUL, 0x0100}, - {"muls", "d,d", "00000010ddddrrrr", 1, AVR_ISA_MUL, 0x0200}, - {"mulsu","a,a", "000000110ddd0rrr", 1, AVR_ISA_MUL, 0x0300}, - {"fmul", "a,a", "000000110ddd1rrr", 1, AVR_ISA_MUL, 0x0308}, - {"fmuls","a,a", "000000111ddd0rrr", 1, AVR_ISA_MUL, 0x0380}, - {"fmulsu","a,a","000000111ddd1rrr", 1, AVR_ISA_MUL, 0x0388}, - {"lpmx", "r,z", "1001000ddddd010+", 1, AVR_ISA_LPMX, 0x9004}, - /* these are for devices that don't exists yet */ - /* >64K program memory, new core */ - {"elpmx","r,z", "1001000ddddd011+", 1, AVR_ISA_ELPMX,0x9006}, - {"espm", "", "1001010111111000", 1, AVR_ISA_ESPM, 0x95f8}, - /* >128K program memory (PC = EIND:Z) */ - {"eicall", "", "1001010100011001", 1, AVR_ISA_EIND, 0x9519}, - {"eijmp", "", "1001010000011001", 1, AVR_ISA_EIND, 0x9419}, - {NULL, NULL, NULL, 0, 0, 0} -}; - - - #define EXP_MOD_NAME(i) exp_mod[i].name #define EXP_MOD_RELOC(i) exp_mod[i].reloc #define EXP_MOD_NEG_RELOC(i) exp_mod[i].neg_reloc @@ -734,6 +551,10 @@ avr_operand (opcode, where, op, line) as_bad (_ ("cannot both predecrement and postincrement")); op_mask |= 0x1001; } + /* avr1 can do "ld r,Z" and "st Z,r" but no other pointer + registers, no predecrement, no postincrement */ + if ((op_mask & 0x100F) && !(avr_mcu->isa & AVR_ISA_SRAM)) + as_bad (_ ("addressing mode not supported")); } break; @@ -866,6 +687,8 @@ avr_operand (opcode, where, op, line) op_mask |= x << 3; } break; + case '?': + break; default: as_bad (_ ("unknown constraint `%c'"), *op); } @@ -1189,20 +1012,10 @@ md_assemble (str) } /* Special case for opcodes with optional operands (lpm, elpm) - - version with operands is listed in avr_opcodes[] with "x" suffix. */ + version with operands exists in avr_opcodes[] in the next entry. */ - if (*str && !(*opcode->constraints)) - { - struct avr_opcodes_s *opc1; - - /* known opcode, so strlen(op) <= 6 and strcat() should be safe */ - strcat(op, "x"); - opc1 = (struct avr_opcodes_s *) hash_find (avr_hash, op); - - /* if unknown, just forget it and use the original opcode */ - if (opc1) - opcode = opc1; - } + if (*str && *opcode->constraints == '?') + ++opcode; if ((opcode->isa & avr_mcu->isa) != opcode->isa) as_bad (_ ("illegal opcode %s for mcu %s"), opcode->name, avr_mcu->name); |