PageRenderTime 49ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/RenderSystems/GL/src/nvparse/vs1.0_inst.cpp

https://bitbucket.org/CaptainOz/ogre
C++ | 1476 lines | 1365 code | 78 blank | 33 comment | 188 complexity | f85bc2b521f7e0897be71eb27ffbddd5 MD5 | raw file
Possible License(s): LGPL-2.1, MIT
  1. #ifdef WIN32
  2. #pragma warning(disable:4786)
  3. #endif
  4. #include "vs1.0_inst.h"
  5. #include <stdio.h>
  6. #include <string>
  7. #include <map>
  8. #include <string.h>
  9. #include "nvparse_errors.h"
  10. #include "nvparse_externs.h"
  11. std::string vs10_transstring;
  12. #if 0
  13. VS10Reg::VS10Reg()
  14. {
  15. type = 0;
  16. index = 0;
  17. sign = 0;
  18. mask = 0;
  19. }
  20. VS10Reg::VS10Reg(const VS10Reg &r)
  21. {
  22. type = r.type;
  23. index = r.index;
  24. sign = r.sign;
  25. mask = r.mask;
  26. }
  27. VS10Reg& VS10Reg::operator=(const VS10Reg &r)
  28. {
  29. if ( this != &r )
  30. {
  31. type = r.type;
  32. index = r.index;
  33. sign = r.sign;
  34. mask = r.mask;
  35. }
  36. return *this;
  37. }
  38. #endif
  39. void VS10Reg::Init()
  40. {
  41. type = 0;
  42. index = -1;
  43. sign = 0;
  44. mask[0] = 'j';
  45. mask[1] = 'j';
  46. mask[2] = 'j';
  47. mask[3] = 'j';
  48. }
  49. int VS10Reg::ValidateIndex()
  50. {
  51. switch( type )
  52. {
  53. case TYPE_TEMPORARY_REG:
  54. if ( index < 0 || index > 11 ) return 0;
  55. else return 1;
  56. break;
  57. case TYPE_VERTEX_ATTRIB_REG:
  58. if ( index < 0 || index > 15 ) return 0;
  59. else return 1;
  60. break;
  61. case TYPE_ADDRESS_REG:
  62. if ( index != 0 ) return 0;
  63. else return 1;
  64. break;
  65. case TYPE_CONSTANT_MEM_REG:
  66. if ( index < 0 || index > 95 ) return 0;
  67. else return 1;
  68. break;
  69. case TYPE_CONSTANT_A0_REG:
  70. case TYPE_CONSTANT_A0_OFFSET_REG:
  71. return 1;
  72. break;
  73. case TYPE_POSITION_RESULT_REG:
  74. return 1;
  75. break;
  76. case TYPE_COLOR_RESULT_REG:
  77. if ( index < 0 || index > 1 ) return 0;
  78. else return 1;
  79. break;
  80. case TYPE_TEXTURE_RESULT_REG:
  81. if ( index < 0 || index > 3 ) return 0;
  82. else return 1;
  83. break;
  84. case TYPE_FOG_RESULT_REG:
  85. return 1;
  86. break;
  87. case TYPE_POINTS_RESULT_REG:
  88. return 1;
  89. break;
  90. default:
  91. errors.set( "VS10Reg::ValidateIndex() Internal Error: unknown register type\n" );
  92. return 1;
  93. }
  94. return 1;
  95. }
  96. void VS10Reg::Translate()
  97. {
  98. char str[16];
  99. if ( sign == -1 )
  100. vs10_transstring.append( "-" );
  101. switch ( type )
  102. {
  103. case TYPE_TEMPORARY_REG:
  104. sprintf( str, "R%d", index );
  105. vs10_transstring.append( str );
  106. break;
  107. case TYPE_VERTEX_ATTRIB_REG:
  108. sprintf( str, "v[%d]", index );
  109. vs10_transstring.append( str );
  110. break;
  111. case TYPE_ADDRESS_REG:
  112. sprintf( str, "A%d", index );
  113. vs10_transstring.append( str );
  114. break;
  115. case TYPE_CONSTANT_MEM_REG:
  116. sprintf( str, "c[%d]", index );
  117. vs10_transstring.append( str );
  118. break;
  119. case TYPE_CONSTANT_A0_REG:
  120. vs10_transstring.append( "c[ A0.x ]" );
  121. break;
  122. case TYPE_CONSTANT_A0_OFFSET_REG:
  123. sprintf( str, "c[ A0.x + %d ]", index );
  124. vs10_transstring.append( str );
  125. break;
  126. case TYPE_POSITION_RESULT_REG:
  127. vs10_transstring.append( "o[HPOS]" );
  128. break;
  129. case TYPE_COLOR_RESULT_REG:
  130. sprintf( str, "o[COL%d]", index );
  131. vs10_transstring.append( str );
  132. break;
  133. case TYPE_TEXTURE_RESULT_REG:
  134. sprintf( str, "o[TEX%d]", index );
  135. vs10_transstring.append( str );
  136. break;
  137. case TYPE_FOG_RESULT_REG:
  138. vs10_transstring.append( "o[FOGC]" );
  139. break;
  140. case TYPE_POINTS_RESULT_REG:
  141. vs10_transstring.append( "o[PSIZ]" );
  142. break;
  143. default:
  144. errors.set( "VS10Reg::Translate() Internal Error: unknown register type\n" );
  145. }
  146. if ( mask[0] != 0 )
  147. {
  148. str[0] = '.';
  149. strncpy( str+1, mask, 4 );
  150. str[5] = 0;
  151. vs10_transstring.append( str );
  152. }
  153. }
  154. VS10Inst::~VS10Inst()
  155. {
  156. if (comment != NULL ) delete [] comment;
  157. }
  158. VS10Inst::VS10Inst()
  159. {
  160. line = -1;
  161. instid = -1;
  162. dst.Init();
  163. src[0].Init();
  164. src[1].Init();
  165. src[2].Init();
  166. comment = NULL;
  167. }
  168. VS10Inst::VS10Inst( int currline )
  169. {
  170. line = currline;
  171. instid = -1;
  172. dst.Init();
  173. src[0].Init();
  174. src[1].Init();
  175. src[2].Init();
  176. comment = NULL;
  177. }
  178. VS10Inst::VS10Inst( const VS10Inst &inst )
  179. {
  180. line = inst.line;
  181. instid = inst.instid;
  182. dst = inst.dst;
  183. src[0] = inst.src[0];
  184. src[1] = inst.src[1];
  185. src[2] = inst.src[2];
  186. if ( inst.comment == NULL )
  187. comment = NULL;
  188. else
  189. {
  190. comment = new char[strlen(inst.comment)+1];
  191. strcpy( comment, inst.comment );
  192. }
  193. }
  194. VS10Inst& VS10Inst::operator=(const VS10Inst &inst)
  195. {
  196. if ( this != &inst )
  197. {
  198. line = inst.line;
  199. instid = inst.instid;
  200. dst = inst.dst;
  201. src[0] = inst.src[0];
  202. src[1] = inst.src[1];
  203. src[2] = inst.src[2];
  204. if ( inst.comment == NULL )
  205. comment = NULL;
  206. else
  207. {
  208. comment = new char[strlen(inst.comment)+1];
  209. strcpy( comment, inst.comment );
  210. }
  211. }
  212. return *this;
  213. }
  214. VS10Inst::VS10Inst(int currline, int inst)
  215. {
  216. line = currline;
  217. instid = inst;
  218. dst.Init();
  219. src[0].Init();
  220. src[1].Init();
  221. src[2].Init();
  222. comment = NULL;
  223. }
  224. VS10Inst::VS10Inst(int currline, int inst, char *cmt)
  225. {
  226. line = currline;
  227. instid = inst;
  228. dst.Init();
  229. src[0].Init();
  230. src[1].Init();
  231. src[2].Init();
  232. comment = cmt;
  233. }
  234. VS10Inst::VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0)
  235. {
  236. line = currline;
  237. instid = inst;
  238. dst = dreg;
  239. src[0] = src0;
  240. src[1].Init();
  241. src[2].Init();
  242. comment = NULL;
  243. }
  244. VS10Inst::VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0, VS10Reg src1)
  245. {
  246. line = currline;
  247. instid = inst;
  248. dst = dreg;
  249. src[0] = src0;
  250. src[1] = src1;
  251. src[2].Init();
  252. comment = NULL;
  253. }
  254. VS10Inst::VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0, VS10Reg src1, VS10Reg src2)
  255. {
  256. line = currline;
  257. instid = inst;
  258. dst = dreg;
  259. src[0] = src0;
  260. src[1] = src1;
  261. src[2] = src2;
  262. comment = NULL;
  263. }
  264. void VS10Inst::Validate( int &vsflag )
  265. {
  266. // Handle comments, noops, and newlines.
  267. if ( instid == VS10_COMMENT || instid == VS10_NOP || instid == -1 ) return;
  268. // Handle the header case.
  269. if ( instid == VS10_HEADER )
  270. {
  271. if ( vsflag == 0 )
  272. {
  273. vsflag = 1;
  274. return;
  275. }
  276. else
  277. {
  278. char temp[128];
  279. sprintf( temp, "(%d) Error: vs.1.0 token already encountered\n", line );
  280. errors.set( temp );
  281. return;
  282. }
  283. }
  284. // Validate register indices are valid.
  285. ValidateRegIndices();
  286. // Verify destination masking is valid.
  287. ValidateDestMask();
  288. // Verify source swizzling is valid.
  289. ValidateSrcMasks();
  290. // Verify destination register is writable.
  291. ValidateDestWritable();
  292. // Verify source registers are readable.
  293. ValidateSrcReadable();
  294. // Verify not reading from multiple vertex attributes or constants
  295. ValidateReadPorts();
  296. }
  297. void VS10Inst::ValidateRegIndices()
  298. {
  299. char temp[256];
  300. int result;
  301. // Destination register.
  302. result = dst.ValidateIndex();
  303. if ( !result )
  304. {
  305. sprintf( temp, "(%d) Error: destination register index out of range\n", line );
  306. errors.set( temp );
  307. }
  308. // Source register.
  309. result = src[0].ValidateIndex();
  310. if ( !result )
  311. {
  312. sprintf( temp, "(%d) Error: source register index out of range\n", line );
  313. errors.set( temp );
  314. }
  315. switch( instid )
  316. {
  317. // Vector operations.
  318. case VS10_MOV:
  319. case VS10_LIT:
  320. break;
  321. // Unary operations.
  322. case VS10_FRC:
  323. break;
  324. // Scalar operations.
  325. case VS10_EXP:
  326. case VS10_EXPP:
  327. case VS10_LOG:
  328. case VS10_LOGP:
  329. case VS10_RCP:
  330. case VS10_RSQ:
  331. break;
  332. // Binary operations.
  333. case VS10_ADD:
  334. case VS10_DP3:
  335. case VS10_DP4:
  336. case VS10_DST:
  337. case VS10_SGE:
  338. case VS10_SLT:
  339. case VS10_SUB:
  340. case VS10_MAX:
  341. case VS10_MIN:
  342. case VS10_MUL:
  343. result = src[1].ValidateIndex();
  344. if ( !result )
  345. {
  346. sprintf( temp, "(%d) Error: second source register index out of range\n", line );
  347. errors.set( temp );
  348. }
  349. break;
  350. case VS10_M3X2:
  351. case VS10_M3X3:
  352. case VS10_M3X4:
  353. case VS10_M4X3:
  354. case VS10_M4X4:
  355. {
  356. result = src[1].ValidateIndex();
  357. if ( !result )
  358. {
  359. sprintf( temp, "(%d) Error: second source register index out of range\n", line );
  360. errors.set( temp );
  361. }
  362. int orig;
  363. orig = src[1].index;
  364. switch( instid )
  365. {
  366. case VS10_M3X2:
  367. src[1].index = src[1].index + 1;
  368. break;
  369. case VS10_M3X3:
  370. case VS10_M4X3:
  371. src[1].index = src[1].index + 2;
  372. break;
  373. case VS10_M3X4:
  374. case VS10_M4X4:
  375. src[1].index = src[1].index + 3;
  376. break;
  377. }
  378. result = src[1].ValidateIndex();
  379. src[1].index = orig;
  380. if ( !result )
  381. {
  382. sprintf( temp, "(%d) Error: macro expansion produces source register index out of range\n", line );
  383. errors.set( temp );
  384. }
  385. }
  386. break;
  387. // Trinary operations.
  388. case VS10_MAD:
  389. result = src[1].ValidateIndex();
  390. if ( !result )
  391. {
  392. sprintf( temp, "(%d) Error: second source register index out of range\n", line );
  393. errors.set( temp );
  394. }
  395. result = src[2].ValidateIndex();
  396. if ( !result )
  397. {
  398. sprintf( temp, "(%d) Error: third source register index out of range\n", line );
  399. errors.set( temp );
  400. }
  401. break;
  402. default:
  403. errors.set( "VS10Inst::ValidateRegIndices() Internal Error: unknown instruction type\n" );
  404. break;
  405. }
  406. }
  407. void VS10Inst::ValidateDestMask()
  408. {
  409. char temp[256];
  410. typedef std::map<char, int> MyMap;
  411. typedef MyMap::value_type MyPair;
  412. static const MyPair pairs[] =
  413. {
  414. MyPair('x',1),
  415. MyPair('y',2),
  416. MyPair('z',3),
  417. MyPair('w',4),
  418. };
  419. static const MyMap swizzleMap(pairs, pairs+(sizeof(pairs)/sizeof(pairs[0])));
  420. if ( dst.mask[0] == 0 ) return;
  421. int i = 1;
  422. while ( i < 4 && dst.mask[i] != 0 )
  423. {
  424. MyMap::const_iterator lastMaskIt = swizzleMap.find(dst.mask[i-1]);
  425. MyMap::const_iterator curMaskIt = swizzleMap.find(dst.mask[i]);
  426. if (lastMaskIt == swizzleMap.end() || curMaskIt == swizzleMap.end() ||
  427. lastMaskIt->second >= curMaskIt->second)
  428. // if ( dst.mask[i-1] >= dst.mask[i] )
  429. {
  430. char mask[5];
  431. strncpy( mask, dst.mask, 4 );
  432. mask[4] = 0;
  433. sprintf( temp, "(%d) Error: destination register has invalid mask: %s\n", line, mask );
  434. errors.set( temp );
  435. break;
  436. }
  437. i++;
  438. }
  439. }
  440. void VS10Inst::ValidateSrcMasks()
  441. {
  442. char temp[256];
  443. char mask[5];
  444. int len;
  445. int i;
  446. switch( instid )
  447. {
  448. // Vector operations.
  449. case VS10_MOV:
  450. case VS10_LIT:
  451. strncpy( mask, src[0].mask, 4 );
  452. mask[4] = 0;
  453. len = strlen( mask );
  454. if ( len != 1 )
  455. {
  456. for ( i = len; i < 4; i++ )
  457. src[0].mask[i] = src[0].mask[len-1];
  458. }
  459. break;
  460. // Unary operations.
  461. case VS10_FRC:
  462. strncpy( mask, src[0].mask, 4 );
  463. mask[4] = 0;
  464. len = strlen( mask );
  465. if ( len != 1 )
  466. {
  467. for ( i = len; i < 4; i++ )
  468. src[0].mask[i] = src[0].mask[len-1];
  469. }
  470. break;
  471. // Scalar operations.
  472. case VS10_EXP:
  473. case VS10_EXPP:
  474. case VS10_LOG:
  475. case VS10_LOGP:
  476. strncpy( mask, src[0].mask, 4 );
  477. mask[4] = 0;
  478. len = strlen( mask );
  479. if( len != 1 )
  480. {
  481. sprintf( temp, "(%d) Error: source register has invalid mask: %s\n", line, mask );
  482. errors.set( temp );
  483. }
  484. break;
  485. case VS10_RCP:
  486. case VS10_RSQ:
  487. strncpy( mask, src[0].mask, 4 );
  488. mask[4] = 0;
  489. len = strlen( mask );
  490. if( len != 0 && len != 1 )
  491. {
  492. sprintf( temp, "(%d) Error: source register has invalid mask: %s\n", line, mask );
  493. errors.set( temp );
  494. }
  495. if ( len == 0 )
  496. {
  497. strcpy( src[0].mask, "w" );
  498. }
  499. break;
  500. // Binary operations.
  501. case VS10_ADD:
  502. case VS10_DP3:
  503. case VS10_DP4:
  504. case VS10_DST:
  505. case VS10_SGE:
  506. case VS10_SLT:
  507. case VS10_SUB:
  508. case VS10_M3X2:
  509. case VS10_M3X3:
  510. case VS10_M3X4:
  511. case VS10_M4X3:
  512. case VS10_M4X4:
  513. case VS10_MAX:
  514. case VS10_MIN:
  515. case VS10_MUL:
  516. strncpy( mask, src[0].mask, 4 );
  517. mask[4] = 0;
  518. len = strlen( mask );
  519. if ( len != 0 && len != 1 )
  520. {
  521. for ( i = len; i < 4; i++ )
  522. src[0].mask[i] = src[0].mask[len-1];
  523. }
  524. strncpy( mask, src[1].mask, 4 );
  525. mask[4] = 0;
  526. len = strlen( mask );
  527. if ( len != 0 && len != 1 )
  528. {
  529. for ( i = len; i < 4; i++ )
  530. src[1].mask[i] = src[1].mask[len-1];
  531. }
  532. break;
  533. // Trinary operations.
  534. case VS10_MAD:
  535. strncpy( mask, src[0].mask, 4 );
  536. mask[4] = 0;
  537. len = strlen( mask );
  538. if ( len != 0 && len != 1 )
  539. {
  540. for ( i = len; i < 4; i++ )
  541. src[0].mask[i] = src[0].mask[len-1];
  542. }
  543. strncpy( mask, src[1].mask, 4 );
  544. mask[4] = 0;
  545. len = strlen( mask );
  546. if ( len != 0 && len != 1 )
  547. {
  548. for ( i = len; i < 4; i++ )
  549. src[1].mask[i] = src[1].mask[len-1];
  550. }
  551. strncpy( mask, src[2].mask, 4 );
  552. mask[4] = 0;
  553. len = strlen( mask );
  554. if ( len != 0 && len != 1 )
  555. {
  556. for ( i = len; i < 4; i++ )
  557. src[2].mask[i] = src[2].mask[len-1];
  558. }
  559. break;
  560. default:
  561. errors.set( "VS10Inst::ValidateSrcMasks() Internal Error: unknown instruction type\n" );
  562. break;
  563. }
  564. }
  565. void VS10Inst::ValidateDestWritable()
  566. {
  567. char temp[256];
  568. switch ( dst.type )
  569. {
  570. case TYPE_TEMPORARY_REG:
  571. case TYPE_POSITION_RESULT_REG:
  572. case TYPE_COLOR_RESULT_REG:
  573. case TYPE_TEXTURE_RESULT_REG:
  574. case TYPE_FOG_RESULT_REG:
  575. case TYPE_POINTS_RESULT_REG:
  576. break;
  577. case TYPE_VERTEX_ATTRIB_REG:
  578. case TYPE_CONSTANT_MEM_REG:
  579. case TYPE_CONSTANT_A0_REG:
  580. case TYPE_CONSTANT_A0_OFFSET_REG:
  581. sprintf( temp, "(%d) Error: destination register is not writable\n", line );
  582. errors.set( temp );
  583. break;
  584. case TYPE_ADDRESS_REG:
  585. if ( instid != VS10_MOV )
  586. {
  587. sprintf( temp, "(%d) Error: destination register is not writable using this instruction\n", line );
  588. errors.set( temp );
  589. }
  590. break;
  591. default:
  592. errors.set( "VS10Inst::ValidateDestWritable() Internal Error: unknown register type\n" );
  593. }
  594. if ( instid == VS10_FRC && dst.type != TYPE_TEMPORARY_REG )
  595. {
  596. sprintf( temp, "(%d) Error: destination register must be a temporary register\n", line );
  597. errors.set( temp );
  598. }
  599. }
  600. void VS10Inst::ValidateSrcReadable()
  601. {
  602. char temp[256];
  603. // Source register.
  604. switch( src[0].type )
  605. {
  606. case TYPE_TEMPORARY_REG:
  607. case TYPE_VERTEX_ATTRIB_REG:
  608. case TYPE_CONSTANT_MEM_REG:
  609. case TYPE_CONSTANT_A0_REG:
  610. case TYPE_CONSTANT_A0_OFFSET_REG:
  611. break;
  612. case TYPE_ADDRESS_REG:
  613. case TYPE_POSITION_RESULT_REG:
  614. case TYPE_COLOR_RESULT_REG:
  615. case TYPE_TEXTURE_RESULT_REG:
  616. case TYPE_FOG_RESULT_REG:
  617. case TYPE_POINTS_RESULT_REG:
  618. sprintf( temp, "(%d) Error: source register is not readable\n", line );
  619. errors.set( temp );
  620. break;
  621. default:
  622. errors.set( "VS10Inst::ValidateSrcReadable() Internal Error: unknown register type\n" );
  623. }
  624. switch( instid )
  625. {
  626. // Vector operations.
  627. case VS10_MOV:
  628. case VS10_LIT:
  629. break;
  630. // Unary operations.
  631. case VS10_FRC:
  632. break;
  633. // Scalar operations.
  634. case VS10_EXP:
  635. case VS10_EXPP:
  636. case VS10_LOG:
  637. case VS10_LOGP:
  638. case VS10_RCP:
  639. case VS10_RSQ:
  640. break;
  641. // Binary operations.
  642. case VS10_ADD:
  643. case VS10_DP3:
  644. case VS10_DP4:
  645. case VS10_DST:
  646. case VS10_SGE:
  647. case VS10_SLT:
  648. case VS10_SUB:
  649. case VS10_M3X2:
  650. case VS10_M3X3:
  651. case VS10_M3X4:
  652. case VS10_M4X3:
  653. case VS10_M4X4:
  654. case VS10_MAX:
  655. case VS10_MIN:
  656. case VS10_MUL:
  657. switch( src[1].type )
  658. {
  659. case TYPE_TEMPORARY_REG:
  660. case TYPE_VERTEX_ATTRIB_REG:
  661. case TYPE_CONSTANT_MEM_REG:
  662. case TYPE_CONSTANT_A0_REG:
  663. case TYPE_CONSTANT_A0_OFFSET_REG:
  664. break;
  665. case TYPE_ADDRESS_REG:
  666. case TYPE_POSITION_RESULT_REG:
  667. case TYPE_COLOR_RESULT_REG:
  668. case TYPE_TEXTURE_RESULT_REG:
  669. case TYPE_FOG_RESULT_REG:
  670. case TYPE_POINTS_RESULT_REG:
  671. sprintf( temp, "(%d) Error: second source register is not readable\n", line );
  672. errors.set( temp );
  673. break;
  674. default:
  675. errors.set( "VS10Inst::ValidateSrcReadable() Internal Error: unknown register type\n" );
  676. }
  677. break;
  678. // Trinary operations.
  679. case VS10_MAD:
  680. switch( src[1].type )
  681. {
  682. case TYPE_TEMPORARY_REG:
  683. case TYPE_VERTEX_ATTRIB_REG:
  684. case TYPE_CONSTANT_MEM_REG:
  685. case TYPE_CONSTANT_A0_REG:
  686. case TYPE_CONSTANT_A0_OFFSET_REG:
  687. break;
  688. case TYPE_ADDRESS_REG:
  689. case TYPE_POSITION_RESULT_REG:
  690. case TYPE_COLOR_RESULT_REG:
  691. case TYPE_TEXTURE_RESULT_REG:
  692. case TYPE_FOG_RESULT_REG:
  693. case TYPE_POINTS_RESULT_REG:
  694. sprintf( temp, "(%d) Error: second source register is not readable\n", line );
  695. errors.set( temp );
  696. break;
  697. default:
  698. errors.set( "VS10Inst::ValidateSrcReadable() Internal Error: unknown register type\n" );
  699. }
  700. switch( src[2].type )
  701. {
  702. case TYPE_TEMPORARY_REG:
  703. case TYPE_VERTEX_ATTRIB_REG:
  704. case TYPE_CONSTANT_MEM_REG:
  705. case TYPE_CONSTANT_A0_REG:
  706. case TYPE_CONSTANT_A0_OFFSET_REG:
  707. break;
  708. case TYPE_ADDRESS_REG:
  709. case TYPE_POSITION_RESULT_REG:
  710. case TYPE_COLOR_RESULT_REG:
  711. case TYPE_TEXTURE_RESULT_REG:
  712. case TYPE_FOG_RESULT_REG:
  713. case TYPE_POINTS_RESULT_REG:
  714. sprintf( temp, "(%d) Error: third source register is not readable\n", line );
  715. errors.set( temp );
  716. break;
  717. default:
  718. errors.set( "VS10Inst::ValidateSrcReadable() Internal Error: unknown register type\n" );
  719. }
  720. break;
  721. default:
  722. errors.set( "VS10Inst::ValidateSrcReadable() Internal Error: unknown register type\n" );
  723. break;
  724. }
  725. }
  726. void VS10Inst::ValidateReadPorts()
  727. {
  728. int constidx[3];
  729. int attribidx[3];
  730. int i;
  731. int acount;
  732. int ccount;
  733. char temp[256];
  734. switch( instid )
  735. {
  736. // Vector operations.
  737. case VS10_MOV:
  738. case VS10_LIT:
  739. break;
  740. // Unary operations.
  741. case VS10_FRC:
  742. break;
  743. // Scalar operations.
  744. case VS10_EXP:
  745. case VS10_EXPP:
  746. case VS10_LOG:
  747. case VS10_LOGP:
  748. case VS10_RCP:
  749. case VS10_RSQ:
  750. break;
  751. // Binary operations.
  752. case VS10_ADD:
  753. case VS10_DP3:
  754. case VS10_DP4:
  755. case VS10_DST:
  756. case VS10_SGE:
  757. case VS10_SLT:
  758. case VS10_SUB:
  759. case VS10_M3X2:
  760. case VS10_M3X3:
  761. case VS10_M3X4:
  762. case VS10_M4X3:
  763. case VS10_M4X4:
  764. case VS10_MAX:
  765. case VS10_MIN:
  766. case VS10_MUL:
  767. acount = 0;
  768. ccount = 0;
  769. for ( i = 0; i < 2; i++ )
  770. {
  771. switch( src[i].type )
  772. {
  773. case TYPE_VERTEX_ATTRIB_REG:
  774. attribidx[acount] = src[i].index;
  775. acount++;
  776. break;
  777. case TYPE_CONSTANT_MEM_REG:
  778. constidx[ccount] = src[i].index;
  779. ccount++;
  780. break;
  781. case TYPE_CONSTANT_A0_REG:
  782. constidx[ccount] = 100 + src[i].index;
  783. ccount++;
  784. break;
  785. case TYPE_CONSTANT_A0_OFFSET_REG:
  786. constidx[ccount] = 200 + src[i].index;
  787. ccount++;
  788. break;
  789. case TYPE_TEMPORARY_REG:
  790. case TYPE_ADDRESS_REG:
  791. case TYPE_POSITION_RESULT_REG:
  792. case TYPE_COLOR_RESULT_REG:
  793. case TYPE_TEXTURE_RESULT_REG:
  794. case TYPE_FOG_RESULT_REG:
  795. case TYPE_POINTS_RESULT_REG:
  796. break;
  797. default:
  798. errors.set( "VS10Inst::ValidateReadPorts() Internal Error: unknown register type\n" );
  799. }
  800. }
  801. if ( acount == 2 )
  802. {
  803. if ( attribidx[0] != attribidx[1] )
  804. {
  805. sprintf( temp, "(%d) Error: multiple unique attribute registers accessed in this instruction\n", line );
  806. errors.set( temp );
  807. }
  808. }
  809. else if ( ccount == 2 )
  810. {
  811. if ( constidx[0] != constidx[1] )
  812. {
  813. sprintf( temp, "(%d) Error: multiple unique constant registers accessed in this instruction\n", line );
  814. errors.set( temp );
  815. }
  816. }
  817. break;
  818. // Trinary operations.
  819. case VS10_MAD:
  820. acount = 0;
  821. ccount = 0;
  822. for ( i = 0; i < 3; i++ )
  823. {
  824. switch( src[i].type )
  825. {
  826. case TYPE_VERTEX_ATTRIB_REG:
  827. attribidx[acount] = src[i].index;
  828. acount++;
  829. break;
  830. case TYPE_CONSTANT_MEM_REG:
  831. constidx[ccount] = src[i].index;
  832. ccount++;
  833. break;
  834. case TYPE_CONSTANT_A0_REG:
  835. constidx[ccount] = 100 + src[i].index;
  836. ccount++;
  837. break;
  838. case TYPE_CONSTANT_A0_OFFSET_REG:
  839. constidx[ccount] = 200 + src[i].index;
  840. ccount++;
  841. break;
  842. case TYPE_TEMPORARY_REG:
  843. case TYPE_ADDRESS_REG:
  844. case TYPE_POSITION_RESULT_REG:
  845. case TYPE_COLOR_RESULT_REG:
  846. case TYPE_TEXTURE_RESULT_REG:
  847. case TYPE_FOG_RESULT_REG:
  848. case TYPE_POINTS_RESULT_REG:
  849. break;
  850. default:
  851. errors.set( "VS10Inst::ValidateReadPorts() Internal Error: unknown register type\n" );
  852. }
  853. }
  854. if ( acount == 3 )
  855. {
  856. if ( attribidx[0] != attribidx[1] || attribidx[1] != attribidx[2] )
  857. {
  858. sprintf( temp, "(%d) Error: multiple unique attribute registers accessed in this instruction\n", line );
  859. errors.set( temp );
  860. }
  861. }
  862. else if ( acount == 2 )
  863. {
  864. if ( attribidx[0] != attribidx[1] )
  865. {
  866. sprintf( temp, "(%d) Error: multiple unique attribute registers accessed in this instruction\n", line );
  867. errors.set( temp );
  868. }
  869. }
  870. else if ( ccount == 3 )
  871. {
  872. if ( constidx[0] != constidx[1] || constidx[1] != constidx[2] )
  873. {
  874. sprintf( temp, "(%d) Error: multiple unique constant registers accessed in this instruction\n", line );
  875. errors.set( temp );
  876. }
  877. }
  878. else if ( ccount == 2 )
  879. {
  880. if ( constidx[0] != constidx[1] )
  881. {
  882. sprintf( temp, "(%d) Error: multiple unique constant registers accessed in this instruction\n", line );
  883. errors.set( temp );
  884. }
  885. }
  886. break;
  887. default:
  888. errors.set( "VS10Inst::ValidateSrcReadable() Internal Error: unknown register type\n" );
  889. break;
  890. }
  891. }
  892. int VS10Inst::Translate()
  893. {
  894. int flag;
  895. int ninstr = 0;
  896. #if DEBUGGING_PURPOSES
  897. char mystr[16];
  898. if ( instid == VS10_HEADER )
  899. {
  900. sprintf( mystr, "%d:\tvs.1.0 (skip)\n", line );
  901. vs10_transstring.append( mystr );
  902. return 0;
  903. }
  904. sprintf( mystr, "%d:\t", line );
  905. vs10_transstring.append( mystr );
  906. #endif
  907. switch( instid )
  908. {
  909. case VS10_ADD:
  910. vs10_transstring.append( "ADD " );
  911. dst.Translate();
  912. vs10_transstring.append( ", " );
  913. src[0].Translate();
  914. vs10_transstring.append( ", " );
  915. src[1].Translate();
  916. ninstr = 1;
  917. break;
  918. case VS10_DP3:
  919. vs10_transstring.append( "DP3 " );
  920. dst.Translate();
  921. vs10_transstring.append( ", " );
  922. src[0].Translate();
  923. vs10_transstring.append( ", " );
  924. src[1].Translate();
  925. ninstr = 1;
  926. break;
  927. case VS10_DP4:
  928. vs10_transstring.append( "DP4 " );
  929. dst.Translate();
  930. vs10_transstring.append( ", " );
  931. src[0].Translate();
  932. vs10_transstring.append( ", " );
  933. src[1].Translate();
  934. ninstr = 1;
  935. break;
  936. case VS10_DST:
  937. vs10_transstring.append( "DST " );
  938. dst.Translate();
  939. vs10_transstring.append( ", " );
  940. src[0].Translate();
  941. vs10_transstring.append( ", " );
  942. src[1].Translate();
  943. ninstr = 1;
  944. break;
  945. case VS10_EXP:
  946. vs10_transstring.append( "EXP " );
  947. dst.Translate();
  948. vs10_transstring.append( ", " );
  949. src[0].Translate();
  950. ninstr = 1;
  951. break;
  952. case VS10_EXPP:
  953. vs10_transstring.append( "EXP " );
  954. dst.Translate();
  955. vs10_transstring.append( ", " );
  956. src[0].Translate();
  957. ninstr = 1;
  958. break;
  959. case VS10_FRC:
  960. char temp[128];
  961. sprintf( temp, "(%d) Error: FRC built-in macro not yet supported.\n", line );
  962. errors.set( temp );
  963. ninstr = 0;
  964. break;
  965. case VS10_LIT:
  966. vs10_transstring.append( "LIT " );
  967. dst.Translate();
  968. vs10_transstring.append( ", " );
  969. src[0].Translate();
  970. ninstr = 1;
  971. break;
  972. case VS10_LOG:
  973. vs10_transstring.append( "LOG " );
  974. dst.Translate();
  975. vs10_transstring.append( ", " );
  976. src[0].Translate();
  977. ninstr = 1;
  978. break;
  979. case VS10_LOGP:
  980. vs10_transstring.append( "LOG " );
  981. dst.Translate();
  982. vs10_transstring.append( ", " );
  983. src[0].Translate();
  984. ninstr = 1;
  985. break;
  986. case VS10_M3X2:
  987. case VS10_M3X3:
  988. case VS10_M3X4:
  989. if ( dst.mask[0] != 0 )
  990. {
  991. ninstr = 0;
  992. int i = 0;
  993. while ( i < 4 && dst.mask[i] != 0 )
  994. {
  995. if ( dst.mask[i] == 'x' )
  996. {
  997. char oldval;
  998. vs10_transstring.append( "DP3 " );
  999. oldval = dst.mask[0];
  1000. dst.mask[0] = 0;
  1001. dst.Translate();
  1002. dst.mask[0] = oldval;
  1003. vs10_transstring.append( ".x, " );
  1004. src[0].Translate();
  1005. vs10_transstring.append( ", " );
  1006. src[1].Translate();
  1007. vs10_transstring.append( ";\n" );
  1008. ninstr++;
  1009. }
  1010. if ( dst.mask[i] == 'y' )
  1011. {
  1012. char oldval;
  1013. int oldindex;
  1014. vs10_transstring.append( "DP3 " );
  1015. oldval = dst.mask[0];
  1016. dst.mask[0] = 0;
  1017. dst.Translate();
  1018. dst.mask[0] = oldval;
  1019. vs10_transstring.append( ".y, " );
  1020. src[0].Translate();
  1021. vs10_transstring.append( ", " );
  1022. oldindex = src[1].index;
  1023. src[1].index = src[1].index + 1;
  1024. src[1].Translate();
  1025. src[1].index = oldindex;
  1026. vs10_transstring.append( ";\n" );
  1027. ninstr++;
  1028. }
  1029. if ( dst.mask[i] == 'z' && (instid == VS10_M3X3 || instid == VS10_M3X4) )
  1030. {
  1031. char oldval;
  1032. int oldindex;
  1033. vs10_transstring.append( "DP3 " );
  1034. oldval = dst.mask[0];
  1035. dst.mask[0] = 0;
  1036. dst.Translate();
  1037. dst.mask[0] = oldval;
  1038. vs10_transstring.append( ".z, " );
  1039. src[0].Translate();
  1040. vs10_transstring.append( ", " );
  1041. oldindex = src[1].index;
  1042. src[1].index = src[1].index + 2;
  1043. src[1].Translate();
  1044. src[1].index = oldindex;
  1045. vs10_transstring.append( ";\n" );
  1046. ninstr++;
  1047. }
  1048. if ( dst.mask[i] == 'w' && instid == VS10_M3X4 )
  1049. {
  1050. char oldval;
  1051. int oldindex;
  1052. vs10_transstring.append( "DP3 " );
  1053. oldval = dst.mask[0];
  1054. dst.mask[0] = 0;
  1055. dst.Translate();
  1056. dst.mask[0] = oldval;
  1057. vs10_transstring.append( ".w, " );
  1058. src[0].Translate();
  1059. vs10_transstring.append( ", " );
  1060. oldindex = src[1].index;
  1061. src[1].index = src[1].index + 3;
  1062. src[1].Translate();
  1063. src[1].index = oldindex;
  1064. vs10_transstring.append( ";\n" );
  1065. ninstr++;
  1066. }
  1067. i++;
  1068. }
  1069. return ninstr;
  1070. }
  1071. else
  1072. {
  1073. ninstr = 0;
  1074. char oldval;
  1075. int oldindex;
  1076. vs10_transstring.append( "DP3 " );
  1077. oldval = dst.mask[0];
  1078. dst.mask[0] = 0;
  1079. dst.Translate();
  1080. dst.mask[0] = oldval;
  1081. vs10_transstring.append( ".x, " );
  1082. src[0].Translate();
  1083. vs10_transstring.append( ", " );
  1084. src[1].Translate();
  1085. vs10_transstring.append( ";\n" );
  1086. ninstr++;
  1087. vs10_transstring.append( "DP3 " );
  1088. oldval = dst.mask[0];
  1089. dst.mask[0] = 0;
  1090. dst.Translate();
  1091. dst.mask[0] = oldval;
  1092. vs10_transstring.append( ".y, " );
  1093. src[0].Translate();
  1094. vs10_transstring.append( ", " );
  1095. oldindex = src[1].index;
  1096. src[1].index = src[1].index + 1;
  1097. src[1].Translate();
  1098. src[1].index = oldindex;
  1099. vs10_transstring.append( ";\n" );
  1100. ninstr++;
  1101. if ( instid == VS10_M3X3 || instid == VS10_M3X4 )
  1102. {
  1103. vs10_transstring.append( "DP3 " );
  1104. oldval = dst.mask[0];
  1105. dst.mask[0] = 0;
  1106. dst.Translate();
  1107. dst.mask[0] = oldval;
  1108. vs10_transstring.append( ".z, " );
  1109. src[0].Translate();
  1110. vs10_transstring.append( ", " );
  1111. oldindex = src[1].index;
  1112. src[1].index = src[1].index + 2;
  1113. src[1].Translate();
  1114. src[1].index = oldindex;
  1115. vs10_transstring.append( ";\n" );
  1116. ninstr++;
  1117. }
  1118. if ( instid == VS10_M3X4 )
  1119. {
  1120. vs10_transstring.append( "DP3 " );
  1121. oldval = dst.mask[0];
  1122. dst.mask[0] = 0;
  1123. dst.Translate();
  1124. dst.mask[0] = oldval;
  1125. vs10_transstring.append( ".w, " );
  1126. src[0].Translate();
  1127. vs10_transstring.append( ", " );
  1128. oldindex = src[1].index;
  1129. src[1].index = src[1].index + 3;
  1130. src[1].Translate();
  1131. src[1].index = oldindex;
  1132. vs10_transstring.append( ";\n" );
  1133. ninstr++;
  1134. }
  1135. return ninstr;
  1136. }
  1137. break;
  1138. case VS10_M4X3:
  1139. case VS10_M4X4:
  1140. if ( dst.mask[0] != 0 )
  1141. {
  1142. ninstr = 0;
  1143. int i = 0;
  1144. while ( i < 4 && dst.mask[i] != 0 )
  1145. {
  1146. if ( dst.mask[i] == 'x' )
  1147. {
  1148. char oldval;
  1149. vs10_transstring.append( "DP4 " );
  1150. oldval = dst.mask[0];
  1151. dst.mask[0] = 0;
  1152. dst.Translate();
  1153. dst.mask[0] = oldval;
  1154. vs10_transstring.append( ".x, " );
  1155. src[0].Translate();
  1156. vs10_transstring.append( ", " );
  1157. src[1].Translate();
  1158. vs10_transstring.append( ";\n" );
  1159. ninstr++;
  1160. }
  1161. if ( dst.mask[i] == 'y' )
  1162. {
  1163. char oldval;
  1164. int oldindex;
  1165. vs10_transstring.append( "DP4 " );
  1166. oldval = dst.mask[0];
  1167. dst.mask[0] = 0;
  1168. dst.Translate();
  1169. dst.mask[0] = oldval;
  1170. vs10_transstring.append( ".y, " );
  1171. src[0].Translate();
  1172. vs10_transstring.append( ", " );
  1173. oldindex = src[1].index;
  1174. src[1].index = src[1].index + 1;
  1175. src[1].Translate();
  1176. src[1].index = oldindex;
  1177. vs10_transstring.append( ";\n" );
  1178. ninstr++;
  1179. }
  1180. if ( dst.mask[i] == 'z' )
  1181. {
  1182. char oldval;
  1183. int oldindex;
  1184. vs10_transstring.append( "DP4 " );
  1185. oldval = dst.mask[0];
  1186. dst.mask[0] = 0;
  1187. dst.Translate();
  1188. dst.mask[0] = oldval;
  1189. vs10_transstring.append( ".z, " );
  1190. src[0].Translate();
  1191. vs10_transstring.append( ", " );
  1192. oldindex = src[1].index;
  1193. src[1].index = src[1].index + 2;
  1194. src[1].Translate();
  1195. src[1].index = oldindex;
  1196. vs10_transstring.append( ";\n" );
  1197. ninstr++;
  1198. }
  1199. if ( dst.mask[i] == 'w' && instid == VS10_M4X4 )
  1200. {
  1201. char oldval;
  1202. int oldindex;
  1203. vs10_transstring.append( "DP4 " );
  1204. oldval = dst.mask[0];
  1205. dst.mask[0] = 0;
  1206. dst.Translate();
  1207. dst.mask[0] = oldval;
  1208. vs10_transstring.append( ".w, " );
  1209. src[0].Translate();
  1210. vs10_transstring.append( ", " );
  1211. oldindex = src[1].index;
  1212. src[1].index = src[1].index + 3;
  1213. src[1].Translate();
  1214. src[1].index = oldindex;
  1215. vs10_transstring.append( ";\n" );
  1216. ninstr++;
  1217. }
  1218. i++;
  1219. }
  1220. return ninstr;
  1221. }
  1222. else
  1223. {
  1224. ninstr = 0;
  1225. char oldval;
  1226. int oldindex;
  1227. vs10_transstring.append( "DP4 " );
  1228. oldval = dst.mask[0];
  1229. dst.mask[0] = 0;
  1230. dst.Translate();
  1231. dst.mask[0] = oldval;
  1232. vs10_transstring.append( ".x, " );
  1233. src[0].Translate();
  1234. vs10_transstring.append( ", " );
  1235. src[1].Translate();
  1236. vs10_transstring.append( ";\n" );
  1237. ninstr++;
  1238. vs10_transstring.append( "DP4 " );
  1239. oldval = dst.mask[0];
  1240. dst.mask[0] = 0;
  1241. dst.Translate();
  1242. dst.mask[0] = oldval;
  1243. vs10_transstring.append( ".y, " );
  1244. src[0].Translate();
  1245. vs10_transstring.append( ", " );
  1246. oldindex = src[1].index;
  1247. src[1].index = src[1].index + 1;
  1248. src[1].Translate();
  1249. src[1].index = oldindex;
  1250. vs10_transstring.append( ";\n" );
  1251. ninstr++;
  1252. vs10_transstring.append( "DP4 " );
  1253. oldval = dst.mask[0];
  1254. dst.mask[0] = 0;
  1255. dst.Translate();
  1256. dst.mask[0] = oldval;
  1257. vs10_transstring.append( ".z, " );
  1258. src[0].Translate();
  1259. vs10_transstring.append( ", " );
  1260. oldindex = src[1].index;
  1261. src[1].index = src[1].index + 2;
  1262. src[1].Translate();
  1263. src[1].index = oldindex;
  1264. vs10_transstring.append( ";\n" );
  1265. ninstr++;
  1266. if ( instid == VS10_M4X4 )
  1267. {
  1268. vs10_transstring.append( "DP4 " );
  1269. oldval = dst.mask[0];
  1270. dst.mask[0] = 0;
  1271. dst.Translate();
  1272. dst.mask[0] = oldval;
  1273. vs10_transstring.append( ".w, " );
  1274. src[0].Translate();
  1275. vs10_transstring.append( ", " );
  1276. oldindex = src[1].index;
  1277. src[1].index = src[1].index + 3;
  1278. src[1].Translate();
  1279. src[1].index = oldindex;
  1280. vs10_transstring.append( ";\n" );
  1281. ninstr++;
  1282. }
  1283. return ninstr;
  1284. }
  1285. break;
  1286. case VS10_MAD:
  1287. vs10_transstring.append( "MAD " );
  1288. dst.Translate();
  1289. vs10_transstring.append( ", " );
  1290. src[0].Translate();
  1291. vs10_transstring.append( ", " );
  1292. src[1].Translate();
  1293. vs10_transstring.append( ", " );
  1294. src[2].Translate();
  1295. ninstr = 1;
  1296. break;
  1297. case VS10_MAX:
  1298. vs10_transstring.append( "MAX " );
  1299. dst.Translate();
  1300. vs10_transstring.append( ", " );
  1301. src[0].Translate();
  1302. vs10_transstring.append( ", " );
  1303. src[1].Translate();
  1304. ninstr = 1;
  1305. break;
  1306. case VS10_MIN:
  1307. vs10_transstring.append( "MIN " );
  1308. dst.Translate();
  1309. vs10_transstring.append( ", " );
  1310. src[0].Translate();
  1311. vs10_transstring.append( ", " );
  1312. src[1].Translate();
  1313. ninstr = 1;
  1314. break;
  1315. case VS10_MOV:
  1316. if ( dst.type == TYPE_ADDRESS_REG )
  1317. vs10_transstring.append( "ARL " );
  1318. else
  1319. vs10_transstring.append( "MOV " );
  1320. dst.Translate();
  1321. vs10_transstring.append( ", " );
  1322. src[0].Translate();
  1323. ninstr = 1;
  1324. break;
  1325. case VS10_MUL:
  1326. vs10_transstring.append( "MUL " );
  1327. dst.Translate();
  1328. vs10_transstring.append( ", " );
  1329. src[0].Translate();
  1330. vs10_transstring.append( ", " );
  1331. src[1].Translate();
  1332. ninstr = 1;
  1333. break;
  1334. case VS10_NOP:
  1335. return 0;
  1336. break;
  1337. case VS10_RCP:
  1338. vs10_transstring.append( "RCP " );
  1339. dst.Translate();
  1340. vs10_transstring.append( ", " );
  1341. src[0].Translate();
  1342. ninstr = 1;
  1343. break;
  1344. case VS10_RSQ:
  1345. vs10_transstring.append( "RSQ " );
  1346. dst.Translate();
  1347. vs10_transstring.append( ", " );
  1348. src[0].Translate();
  1349. ninstr = 1;
  1350. break;
  1351. case VS10_SGE:
  1352. vs10_transstring.append( "SGE " );
  1353. dst.Translate();
  1354. vs10_transstring.append( ", " );
  1355. src[0].Translate();
  1356. vs10_transstring.append( ", " );
  1357. src[1].Translate();
  1358. ninstr = 1;
  1359. break;
  1360. case VS10_SLT:
  1361. vs10_transstring.append( "SLT " );
  1362. dst.Translate();
  1363. vs10_transstring.append( ", " );
  1364. src[0].Translate();
  1365. vs10_transstring.append( ", " );
  1366. src[1].Translate();
  1367. ninstr = 1;
  1368. break;
  1369. case VS10_SUB:
  1370. vs10_transstring.append( "ADD " );
  1371. dst.Translate();
  1372. vs10_transstring.append( ", " );
  1373. src[0].Translate();
  1374. vs10_transstring.append( ", " );
  1375. flag = src[1].sign;
  1376. if ( flag == -1 ) src[1].sign = 1;
  1377. else src[1].sign = -1;
  1378. src[1].Translate();
  1379. src[1].sign = flag;
  1380. ninstr = 1;
  1381. break;
  1382. case VS10_COMMENT:
  1383. vs10_transstring.append( comment );
  1384. return 0;
  1385. break;
  1386. case VS10_HEADER:
  1387. //vs10_transstring.append( "!!VP1.0\n" );
  1388. return 0;
  1389. break;
  1390. case -1:
  1391. vs10_transstring.append( "\n" );
  1392. return 0;
  1393. default:
  1394. errors.set( "VS10Inst::Translate() Internal Error: unknown instruction type\n" );
  1395. }
  1396. vs10_transstring.append( ";\n" );
  1397. return ninstr;
  1398. }