1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * A small micro-assembler. It is intentionally kept simple, does only 7 * support a subset of instructions, and does not try to hide pipeline 8 * effects like branch delay slots. 9 * 10 * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer 11 * Copyright (C) 2005, 2007 Maciej W. Rozycki 12 * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) 13 * Copyright (C) 2012, 2013 MIPS Technologies, Inc. All rights reserved. 14 */ 15 16 enum fields { 17 RS = 0x001, 18 RT = 0x002, 19 RD = 0x004, 20 RE = 0x008, 21 SIMM = 0x010, 22 UIMM = 0x020, 23 BIMM = 0x040, 24 JIMM = 0x080, 25 FUNC = 0x100, 26 SET = 0x200, 27 SCIMM = 0x400, 28 SIMM9 = 0x800, 29 }; 30 31 #define OP_MASK 0x3f 32 #define OP_SH 26 33 #define RD_MASK 0x1f 34 #define RD_SH 11 35 #define RE_MASK 0x1f 36 #define RE_SH 6 37 #define IMM_MASK 0xffff 38 #define IMM_SH 0 39 #define JIMM_MASK 0x3ffffff 40 #define JIMM_SH 0 41 #define FUNC_MASK 0x3f 42 #define FUNC_SH 0 43 #define SET_MASK 0x7 44 #define SET_SH 0 45 #define SIMM9_SH 7 46 #define SIMM9_MASK 0x1ff 47 48 enum opcode { 49 insn_addiu, insn_addu, insn_and, insn_andi, insn_bbit0, insn_bbit1, 50 insn_beq, insn_beql, insn_bgez, insn_bgezl, insn_bgtz, insn_blez, 51 insn_bltz, insn_bltzl, insn_bne, insn_break, insn_cache, insn_cfc1, 52 insn_cfcmsa, insn_ctc1, insn_ctcmsa, insn_daddiu, insn_daddu, insn_ddivu, 53 insn_di, insn_dins, insn_dinsm, insn_dinsu, insn_divu, insn_dmfc0, 54 insn_dmtc0, insn_dmultu, insn_drotr, insn_drotr32, insn_dsbh, insn_dshd, 55 insn_dsll, insn_dsll32, insn_dsllv, insn_dsra, insn_dsra32, insn_dsrav, 56 insn_dsrl, insn_dsrl32, insn_dsrlv, insn_dsubu, insn_eret, insn_ext, 57 insn_ins, insn_j, insn_jal, insn_jalr, insn_jr, insn_lb, insn_lbu, 58 insn_ld, insn_lddir, insn_ldpte, insn_ldx, insn_lh, insn_lhu, 59 insn_ll, insn_lld, insn_lui, insn_lw, insn_lwu, insn_lwx, insn_mfc0, 60 insn_mfhc0, insn_mfhi, insn_mflo, insn_movn, insn_movz, insn_mtc0, 61 insn_mthc0, insn_mthi, insn_mtlo, insn_mul, insn_multu, insn_nor, 62 insn_or, insn_ori, insn_pref, insn_rfe, insn_rotr, insn_sb, 63 insn_sc, insn_scd, insn_sd, insn_sh, insn_sll, insn_sllv, 64 insn_slt, insn_slti, insn_sltiu, insn_sltu, insn_sra, insn_srav, 65 insn_srl, insn_srlv, insn_subu, insn_sw, insn_sync, insn_syscall, 66 insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_wait, insn_wsbh, 67 insn_xor, insn_xori, insn_yield, 68 insn_invalid /* insn_invalid must be last */ 69 }; 70 71 struct insn { 72 u32 match; 73 enum fields fields; 74 }; 75 76 static inline u32 build_rs(u32 arg) 77 { 78 WARN(arg & ~RS_MASK, KERN_WARNING "Micro-assembler field overflow\n"); 79 80 return (arg & RS_MASK) << RS_SH; 81 } 82 83 static inline u32 build_rt(u32 arg) 84 { 85 WARN(arg & ~RT_MASK, KERN_WARNING "Micro-assembler field overflow\n"); 86 87 return (arg & RT_MASK) << RT_SH; 88 } 89 90 static inline u32 build_rd(u32 arg) 91 { 92 WARN(arg & ~RD_MASK, KERN_WARNING "Micro-assembler field overflow\n"); 93 94 return (arg & RD_MASK) << RD_SH; 95 } 96 97 static inline u32 build_re(u32 arg) 98 { 99 WARN(arg & ~RE_MASK, KERN_WARNING "Micro-assembler field overflow\n"); 100 101 return (arg & RE_MASK) << RE_SH; 102 } 103 104 static inline u32 build_simm(s32 arg) 105 { 106 WARN(arg > 0x7fff || arg < -0x8000, 107 KERN_WARNING "Micro-assembler field overflow\n"); 108 109 return arg & 0xffff; 110 } 111 112 static inline u32 build_uimm(u32 arg) 113 { 114 WARN(arg & ~IMM_MASK, KERN_WARNING "Micro-assembler field overflow\n"); 115 116 return arg & IMM_MASK; 117 } 118 119 static inline u32 build_scimm(u32 arg) 120 { 121 WARN(arg & ~SCIMM_MASK, 122 KERN_WARNING "Micro-assembler field overflow\n"); 123 124 return (arg & SCIMM_MASK) << SCIMM_SH; 125 } 126 127 static inline u32 build_scimm9(s32 arg) 128 { 129 WARN((arg > 0xff || arg < -0x100), 130 KERN_WARNING "Micro-assembler field overflow\n"); 131 132 return (arg & SIMM9_MASK) << SIMM9_SH; 133 } 134 135 static inline u32 build_func(u32 arg) 136 { 137 WARN(arg & ~FUNC_MASK, KERN_WARNING "Micro-assembler field overflow\n"); 138 139 return arg & FUNC_MASK; 140 } 141 142 static inline u32 build_set(u32 arg) 143 { 144 WARN(arg & ~SET_MASK, KERN_WARNING "Micro-assembler field overflow\n"); 145 146 return arg & SET_MASK; 147 } 148 149 static void build_insn(u32 **buf, enum opcode opc, ...); 150 151 #define I_u1u2u3(op) \ 152 Ip_u1u2u3(op) \ 153 { \ 154 build_insn(buf, insn##op, a, b, c); \ 155 } \ 156 UASM_EXPORT_SYMBOL(uasm_i##op); 157 158 #define I_s3s1s2(op) \ 159 Ip_s3s1s2(op) \ 160 { \ 161 build_insn(buf, insn##op, b, c, a); \ 162 } \ 163 UASM_EXPORT_SYMBOL(uasm_i##op); 164 165 #define I_u2u1u3(op) \ 166 Ip_u2u1u3(op) \ 167 { \ 168 build_insn(buf, insn##op, b, a, c); \ 169 } \ 170 UASM_EXPORT_SYMBOL(uasm_i##op); 171 172 #define I_u3u2u1(op) \ 173 Ip_u3u2u1(op) \ 174 { \ 175 build_insn(buf, insn##op, c, b, a); \ 176 } \ 177 UASM_EXPORT_SYMBOL(uasm_i##op); 178 179 #define I_u3u1u2(op) \ 180 Ip_u3u1u2(op) \ 181 { \ 182 build_insn(buf, insn##op, b, c, a); \ 183 } \ 184 UASM_EXPORT_SYMBOL(uasm_i##op); 185 186 #define I_u1u2s3(op) \ 187 Ip_u1u2s3(op) \ 188 { \ 189 build_insn(buf, insn##op, a, b, c); \ 190 } \ 191 UASM_EXPORT_SYMBOL(uasm_i##op); 192 193 #define I_u2s3u1(op) \ 194 Ip_u2s3u1(op) \ 195 { \ 196 build_insn(buf, insn##op, c, a, b); \ 197 } \ 198 UASM_EXPORT_SYMBOL(uasm_i##op); 199 200 #define I_u2u1s3(op) \ 201 Ip_u2u1s3(op) \ 202 { \ 203 build_insn(buf, insn##op, b, a, c); \ 204 } \ 205 UASM_EXPORT_SYMBOL(uasm_i##op); 206 207 #define I_u2u1msbu3(op) \ 208 Ip_u2u1msbu3(op) \ 209 { \ 210 build_insn(buf, insn##op, b, a, c+d-1, c); \ 211 } \ 212 UASM_EXPORT_SYMBOL(uasm_i##op); 213 214 #define I_u2u1msb32u3(op) \ 215 Ip_u2u1msbu3(op) \ 216 { \ 217 build_insn(buf, insn##op, b, a, c+d-33, c); \ 218 } \ 219 UASM_EXPORT_SYMBOL(uasm_i##op); 220 221 #define I_u2u1msb32msb3(op) \ 222 Ip_u2u1msbu3(op) \ 223 { \ 224 build_insn(buf, insn##op, b, a, c+d-33, c-32); \ 225 } \ 226 UASM_EXPORT_SYMBOL(uasm_i##op); 227 228 #define I_u2u1msbdu3(op) \ 229 Ip_u2u1msbu3(op) \ 230 { \ 231 build_insn(buf, insn##op, b, a, d-1, c); \ 232 } \ 233 UASM_EXPORT_SYMBOL(uasm_i##op); 234 235 #define I_u1u2(op) \ 236 Ip_u1u2(op) \ 237 { \ 238 build_insn(buf, insn##op, a, b); \ 239 } \ 240 UASM_EXPORT_SYMBOL(uasm_i##op); 241 242 #define I_u2u1(op) \ 243 Ip_u1u2(op) \ 244 { \ 245 build_insn(buf, insn##op, b, a); \ 246 } \ 247 UASM_EXPORT_SYMBOL(uasm_i##op); 248 249 #define I_u1s2(op) \ 250 Ip_u1s2(op) \ 251 { \ 252 build_insn(buf, insn##op, a, b); \ 253 } \ 254 UASM_EXPORT_SYMBOL(uasm_i##op); 255 256 #define I_u1(op) \ 257 Ip_u1(op) \ 258 { \ 259 build_insn(buf, insn##op, a); \ 260 } \ 261 UASM_EXPORT_SYMBOL(uasm_i##op); 262 263 #define I_0(op) \ 264 Ip_0(op) \ 265 { \ 266 build_insn(buf, insn##op); \ 267 } \ 268 UASM_EXPORT_SYMBOL(uasm_i##op); 269 270 I_u2u1s3(_addiu) 271 I_u3u1u2(_addu) 272 I_u2u1u3(_andi) 273 I_u3u1u2(_and) 274 I_u1u2s3(_beq) 275 I_u1u2s3(_beql) 276 I_u1s2(_bgez) 277 I_u1s2(_bgezl) 278 I_u1s2(_bgtz) 279 I_u1s2(_blez) 280 I_u1s2(_bltz) 281 I_u1s2(_bltzl) 282 I_u1u2s3(_bne) 283 I_u1(_break) 284 I_u2s3u1(_cache) 285 I_u1u2(_cfc1) 286 I_u2u1(_cfcmsa) 287 I_u1u2(_ctc1) 288 I_u2u1(_ctcmsa) 289 I_u1u2(_ddivu) 290 I_u1u2u3(_dmfc0) 291 I_u1u2u3(_dmtc0) 292 I_u1u2(_dmultu) 293 I_u2u1s3(_daddiu) 294 I_u3u1u2(_daddu) 295 I_u1(_di); 296 I_u1u2(_divu) 297 I_u2u1(_dsbh); 298 I_u2u1(_dshd); 299 I_u2u1u3(_dsll) 300 I_u2u1u3(_dsll32) 301 I_u3u2u1(_dsllv) 302 I_u2u1u3(_dsra) 303 I_u2u1u3(_dsra32) 304 I_u3u2u1(_dsrav) 305 I_u2u1u3(_dsrl) 306 I_u2u1u3(_dsrl32) 307 I_u3u2u1(_dsrlv) 308 I_u2u1u3(_drotr) 309 I_u2u1u3(_drotr32) 310 I_u3u1u2(_dsubu) 311 I_0(_eret) 312 I_u2u1msbdu3(_ext) 313 I_u2u1msbu3(_ins) 314 I_u1(_j) 315 I_u1(_jal) 316 I_u2u1(_jalr) 317 I_u1(_jr) 318 I_u2s3u1(_lb) 319 I_u2s3u1(_lbu) 320 I_u2s3u1(_ld) 321 I_u2s3u1(_lh) 322 I_u2s3u1(_lhu) 323 I_u2s3u1(_ll) 324 I_u2s3u1(_lld) 325 I_u1s2(_lui) 326 I_u2s3u1(_lw) 327 I_u2s3u1(_lwu) 328 I_u1u2u3(_mfc0) 329 I_u1u2u3(_mfhc0) 330 I_u3u1u2(_movn) 331 I_u3u1u2(_movz) 332 I_u1(_mfhi) 333 I_u1(_mflo) 334 I_u1u2u3(_mtc0) 335 I_u1u2u3(_mthc0) 336 I_u1(_mthi) 337 I_u1(_mtlo) 338 I_u3u1u2(_mul) 339 I_u1u2(_multu) 340 I_u3u1u2(_nor) 341 I_u3u1u2(_or) 342 I_u2u1u3(_ori) 343 I_0(_rfe) 344 I_u2s3u1(_sb) 345 I_u2s3u1(_sc) 346 I_u2s3u1(_scd) 347 I_u2s3u1(_sd) 348 I_u2s3u1(_sh) 349 I_u2u1u3(_sll) 350 I_u3u2u1(_sllv) 351 I_s3s1s2(_slt) 352 I_u2u1s3(_slti) 353 I_u2u1s3(_sltiu) 354 I_u3u1u2(_sltu) 355 I_u2u1u3(_sra) 356 I_u3u2u1(_srav) 357 I_u2u1u3(_srl) 358 I_u3u2u1(_srlv) 359 I_u2u1u3(_rotr) 360 I_u3u1u2(_subu) 361 I_u2s3u1(_sw) 362 I_u1(_sync) 363 I_0(_tlbp) 364 I_0(_tlbr) 365 I_0(_tlbwi) 366 I_0(_tlbwr) 367 I_u1(_wait); 368 I_u2u1(_wsbh) 369 I_u3u1u2(_xor) 370 I_u2u1u3(_xori) 371 I_u2u1(_yield) 372 I_u2u1msbu3(_dins); 373 I_u2u1msb32u3(_dinsm); 374 I_u2u1msb32msb3(_dinsu); 375 I_u1(_syscall); 376 I_u1u2s3(_bbit0); 377 I_u1u2s3(_bbit1); 378 I_u3u1u2(_lwx) 379 I_u3u1u2(_ldx) 380 I_u1u2(_ldpte) 381 I_u2u1u3(_lddir) 382 383 #ifdef CONFIG_CPU_CAVIUM_OCTEON 384 #include <asm/octeon/octeon.h> 385 void uasm_i_pref(u32 **buf, unsigned int a, signed int b, 386 unsigned int c) 387 { 388 if (CAVIUM_OCTEON_DCACHE_PREFETCH_WAR && a <= 24 && a != 5) 389 /* 390 * As per erratum Core-14449, replace prefetches 0-4, 391 * 6-24 with 'pref 28'. 392 */ 393 build_insn(buf, insn_pref, c, 28, b); 394 else 395 build_insn(buf, insn_pref, c, a, b); 396 } 397 UASM_EXPORT_SYMBOL(uasm_i_pref); 398 #else 399 I_u2s3u1(_pref) 400 #endif 401 402 /* Handle labels. */ 403 void uasm_build_label(struct uasm_label **lab, u32 *addr, int lid) 404 { 405 (*lab)->addr = addr; 406 (*lab)->lab = lid; 407 (*lab)++; 408 } 409 UASM_EXPORT_SYMBOL(uasm_build_label); 410 411 int uasm_in_compat_space_p(long addr) 412 { 413 /* Is this address in 32bit compat space? */ 414 return addr == (int)addr; 415 } 416 UASM_EXPORT_SYMBOL(uasm_in_compat_space_p); 417 418 static int uasm_rel_highest(long val) 419 { 420 #ifdef CONFIG_64BIT 421 return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000; 422 #else 423 return 0; 424 #endif 425 } 426 427 static int uasm_rel_higher(long val) 428 { 429 #ifdef CONFIG_64BIT 430 return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000; 431 #else 432 return 0; 433 #endif 434 } 435 436 int uasm_rel_hi(long val) 437 { 438 return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000; 439 } 440 UASM_EXPORT_SYMBOL(uasm_rel_hi); 441 442 int uasm_rel_lo(long val) 443 { 444 return ((val & 0xffff) ^ 0x8000) - 0x8000; 445 } 446 UASM_EXPORT_SYMBOL(uasm_rel_lo); 447 448 void UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr) 449 { 450 if (!uasm_in_compat_space_p(addr)) { 451 uasm_i_lui(buf, rs, uasm_rel_highest(addr)); 452 if (uasm_rel_higher(addr)) 453 uasm_i_daddiu(buf, rs, rs, uasm_rel_higher(addr)); 454 if (uasm_rel_hi(addr)) { 455 uasm_i_dsll(buf, rs, rs, 16); 456 uasm_i_daddiu(buf, rs, rs, 457 uasm_rel_hi(addr)); 458 uasm_i_dsll(buf, rs, rs, 16); 459 } else 460 uasm_i_dsll32(buf, rs, rs, 0); 461 } else 462 uasm_i_lui(buf, rs, uasm_rel_hi(addr)); 463 } 464 UASM_EXPORT_SYMBOL(UASM_i_LA_mostly); 465 466 void UASM_i_LA(u32 **buf, unsigned int rs, long addr) 467 { 468 UASM_i_LA_mostly(buf, rs, addr); 469 if (uasm_rel_lo(addr)) { 470 if (!uasm_in_compat_space_p(addr)) 471 uasm_i_daddiu(buf, rs, rs, 472 uasm_rel_lo(addr)); 473 else 474 uasm_i_addiu(buf, rs, rs, 475 uasm_rel_lo(addr)); 476 } 477 } 478 UASM_EXPORT_SYMBOL(UASM_i_LA); 479 480 /* Handle relocations. */ 481 void uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid) 482 { 483 (*rel)->addr = addr; 484 (*rel)->type = R_MIPS_PC16; 485 (*rel)->lab = lid; 486 (*rel)++; 487 } 488 UASM_EXPORT_SYMBOL(uasm_r_mips_pc16); 489 490 static inline void __resolve_relocs(struct uasm_reloc *rel, 491 struct uasm_label *lab); 492 493 void uasm_resolve_relocs(struct uasm_reloc *rel, 494 struct uasm_label *lab) 495 { 496 struct uasm_label *l; 497 498 for (; rel->lab != UASM_LABEL_INVALID; rel++) 499 for (l = lab; l->lab != UASM_LABEL_INVALID; l++) 500 if (rel->lab == l->lab) 501 __resolve_relocs(rel, l); 502 } 503 UASM_EXPORT_SYMBOL(uasm_resolve_relocs); 504 505 void uasm_move_relocs(struct uasm_reloc *rel, u32 *first, u32 *end, 506 long off) 507 { 508 for (; rel->lab != UASM_LABEL_INVALID; rel++) 509 if (rel->addr >= first && rel->addr < end) 510 rel->addr += off; 511 } 512 UASM_EXPORT_SYMBOL(uasm_move_relocs); 513 514 void uasm_move_labels(struct uasm_label *lab, u32 *first, u32 *end, 515 long off) 516 { 517 for (; lab->lab != UASM_LABEL_INVALID; lab++) 518 if (lab->addr >= first && lab->addr < end) 519 lab->addr += off; 520 } 521 UASM_EXPORT_SYMBOL(uasm_move_labels); 522 523 void uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab, 524 u32 *first, u32 *end, u32 *target) 525 { 526 long off = (long)(target - first); 527 528 memcpy(target, first, (end - first) * sizeof(u32)); 529 530 uasm_move_relocs(rel, first, end, off); 531 uasm_move_labels(lab, first, end, off); 532 } 533 UASM_EXPORT_SYMBOL(uasm_copy_handler); 534 535 int uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr) 536 { 537 for (; rel->lab != UASM_LABEL_INVALID; rel++) { 538 if (rel->addr == addr 539 && (rel->type == R_MIPS_PC16 540 || rel->type == R_MIPS_26)) 541 return 1; 542 } 543 544 return 0; 545 } 546 UASM_EXPORT_SYMBOL(uasm_insn_has_bdelay); 547 548 /* Convenience functions for labeled branches. */ 549 void uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, 550 int lid) 551 { 552 uasm_r_mips_pc16(r, *p, lid); 553 uasm_i_bltz(p, reg, 0); 554 } 555 UASM_EXPORT_SYMBOL(uasm_il_bltz); 556 557 void uasm_il_b(u32 **p, struct uasm_reloc **r, int lid) 558 { 559 uasm_r_mips_pc16(r, *p, lid); 560 uasm_i_b(p, 0); 561 } 562 UASM_EXPORT_SYMBOL(uasm_il_b); 563 564 void uasm_il_beq(u32 **p, struct uasm_reloc **r, unsigned int r1, 565 unsigned int r2, int lid) 566 { 567 uasm_r_mips_pc16(r, *p, lid); 568 uasm_i_beq(p, r1, r2, 0); 569 } 570 UASM_EXPORT_SYMBOL(uasm_il_beq); 571 572 void uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, 573 int lid) 574 { 575 uasm_r_mips_pc16(r, *p, lid); 576 uasm_i_beqz(p, reg, 0); 577 } 578 UASM_EXPORT_SYMBOL(uasm_il_beqz); 579 580 void uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, 581 int lid) 582 { 583 uasm_r_mips_pc16(r, *p, lid); 584 uasm_i_beqzl(p, reg, 0); 585 } 586 UASM_EXPORT_SYMBOL(uasm_il_beqzl); 587 588 void uasm_il_bne(u32 **p, struct uasm_reloc **r, unsigned int reg1, 589 unsigned int reg2, int lid) 590 { 591 uasm_r_mips_pc16(r, *p, lid); 592 uasm_i_bne(p, reg1, reg2, 0); 593 } 594 UASM_EXPORT_SYMBOL(uasm_il_bne); 595 596 void uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, 597 int lid) 598 { 599 uasm_r_mips_pc16(r, *p, lid); 600 uasm_i_bnez(p, reg, 0); 601 } 602 UASM_EXPORT_SYMBOL(uasm_il_bnez); 603 604 void uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, 605 int lid) 606 { 607 uasm_r_mips_pc16(r, *p, lid); 608 uasm_i_bgezl(p, reg, 0); 609 } 610 UASM_EXPORT_SYMBOL(uasm_il_bgezl); 611 612 void uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, 613 int lid) 614 { 615 uasm_r_mips_pc16(r, *p, lid); 616 uasm_i_bgez(p, reg, 0); 617 } 618 UASM_EXPORT_SYMBOL(uasm_il_bgez); 619 620 void uasm_il_bbit0(u32 **p, struct uasm_reloc **r, unsigned int reg, 621 unsigned int bit, int lid) 622 { 623 uasm_r_mips_pc16(r, *p, lid); 624 uasm_i_bbit0(p, reg, bit, 0); 625 } 626 UASM_EXPORT_SYMBOL(uasm_il_bbit0); 627 628 void uasm_il_bbit1(u32 **p, struct uasm_reloc **r, unsigned int reg, 629 unsigned int bit, int lid) 630 { 631 uasm_r_mips_pc16(r, *p, lid); 632 uasm_i_bbit1(p, reg, bit, 0); 633 } 634 UASM_EXPORT_SYMBOL(uasm_il_bbit1); 635