| @@ -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 | 225 | ST_FUNC void asm_opcode(TCCState *s1, int token) |
| 183 | 226 | { |
| 184 | 227 | switch (token) { |
| @@ -204,6 +247,11 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 19 unmodified lines |
| 204 | 247 | asm_unary_opcode(s1, token); |
| 205 | 248 | return; |
| 206 | 249 | |
| 250 | + case TOK_ASM_lui: |
| 251 | + case TOK_ASM_auipc: |
| 252 | + asm_binary_opcode(s1, token); |
| 253 | + return; |
| 254 | + |
| 207 | 255 | default: |
| 208 | 256 | expect("known instruction"); |
| 209 | 257 | } |