| @@ -179,6 +179,49 @@ static void asm_unary_opcode(TCCState *s1, int token) · 178 unmodified lines |
| 179 | } | 179 | } |
| 180 | } | 180 | } |
| 181 | | 181 | |
| | 182 | static void asm_emit_u(int token, uint32_t opcode, const Operand* rd, const Operand* rs2) |
| | 183 | { |
| | 184 | if (rd->type != OP_REG) { |
| | 185 | tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL)); |
| | 186 | return; |
| | 187 | } |
| | 188 | if (rs2->type != OP_IM12S && rs2->type != OP_IM32) { |
| | 189 | tcc_error("'%s': Expected second source operand that is an immediate value", get_tok_str(token, NULL)); |
| | 190 | return; |
| | 191 | } else if (rs2->e.v >= 0x100000) { |
| | 192 | tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 0xfffff", get_tok_str(token, NULL)); |
| | 193 | return; |
| | 194 | } |
| | 195 | /* U-type instruction: |
| | 196 | 31...12 imm[31:12] |
| | 197 | 11...7 rd |
| | 198 | 6...0 opcode */ |
| | 199 | gen_le32(opcode | ENCODE_RD(rd->reg) | (rs2->e.v << 12)); |
| | 200 | } |
| | 201 | |
| | 202 | static void asm_binary_opcode(TCCState* s1, int token) |
| | 203 | { |
| | 204 | Operand ops[2]; |
| | 205 | parse_operand(s1, &ops[0]); |
| | 206 | if (tok == ',') |
| | 207 | next(); |
| | 208 | else |
| | 209 | expect("','"); |
| | 210 | parse_operand(s1, &ops[1]); |
| | 211 | |
| | 212 | switch (token) { |
| | 213 | case TOK_ASM_lui: |
| | 214 | asm_emit_u(token, (0xD << 2) | 3, &ops[0], &ops[1]); |
| | 215 | return; |
| | 216 | case TOK_ASM_auipc: |
| | 217 | asm_emit_u(token, (0x05 << 2) | 3, &ops[0], &ops[1]); |
| | 218 | return; |
| | 219 | default: |
| | 220 | expect("binary instruction"); |
| | 221 | } |
| | 222 | } |
| | 223 | |
| | 224 | |
| 182 | ST_FUNC void asm_opcode(TCCState *s1, int token) | 225 | ST_FUNC void asm_opcode(TCCState *s1, int token) |
| 183 | { | 226 | { |
| 184 | switch (token) { | 227 | switch (token) { |
| @@ -204,6 +247,11 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 19 unmodified lines |
| 204 | asm_unary_opcode(s1, token); | 247 | asm_unary_opcode(s1, token); |
| 205 | return; | 248 | return; |
| 206 | | 249 | |
| | 250 | case TOK_ASM_lui: |
| | 251 | case TOK_ASM_auipc: |
| | 252 | asm_binary_opcode(s1, token); |
| | 253 | return; |
| | 254 | |
| 207 | default: | 255 | default: |
| 208 | expect("known instruction"); | 256 | expect("known instruction"); |
| 209 | } | 257 | } |