cgcpu.pas 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. This unit implements the code generator for the i386
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit cgcpu;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. cgbase,cgobj,aasm,cpuasm,cpubase,cpuinfo;
  23. type
  24. tcg386 = class(tcg)
  25. { passing parameters, per default the parameter is pushed }
  26. { nr gives the number of the parameter (enumerated from }
  27. { left to right), this allows to move the parameter to }
  28. { register, if the cpu supports register calling }
  29. { conventions }
  30. procedure a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;nr : longint);override;
  31. procedure a_param_const(list : taasmoutput;size : tcgsize;a : aword;nr : longint);override;
  32. procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;nr : longint);override;
  33. procedure a_paramaddr_ref(list : taasmoutput;const r : treference;nr : longint);override;
  34. procedure a_call_name(list : taasmoutput;const s : string;
  35. offset : longint);override;
  36. procedure a_op_const_reg(list : taasmoutput; Op: TOpCG; a: AWord; reg: TRegister); override;
  37. procedure a_op_const_ref(list : taasmoutput; Op: TOpCG; size: TCGSize; a: AWord; const ref: TReference); override;
  38. procedure a_op_reg_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; src, dst: TRegister); override;
  39. procedure a_op_ref_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; const ref: TReference; reg: TRegister); override;
  40. procedure a_op_reg_ref(list : taasmoutput; Op: TOpCG; size: TCGSize;reg: TRegister; const ref: TReference); override;
  41. { move instructions }
  42. procedure a_load_const_reg(list : taasmoutput; size: tcgsize; a : aword;reg : tregister);override;
  43. procedure a_load_const_ref(list : taasmoutput; size: tcgsize; a : aword;const ref : treference);override;
  44. procedure a_load_reg_ref(list : taasmoutput; size: tcgsize; reg : tregister;const ref : treference);override;
  45. procedure a_load_ref_reg(list : taasmoutput;size : tcgsize;const ref : treference;reg : tregister);override;
  46. procedure a_load_reg_reg(list : taasmoutput;size : tcgsize;reg1,reg2 : tregister);override;
  47. { comparison operations }
  48. procedure a_cmp_const_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;reg : tregister;
  49. l : tasmlabel);override;
  50. procedure a_cmp_const_ref_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;const ref : treference;
  51. l : tasmlabel);override;
  52. procedure a_cmp_reg_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : tasmlabel); override;
  53. procedure a_cmp_ref_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;const ref: treference; reg : tregister; l : tasmlabel); override;
  54. procedure a_jmp_cond(list : taasmoutput;cond : TOpCmp;l: tasmlabel); override;
  55. procedure g_flags2reg(list: taasmoutput; const f: tresflags; reg: TRegister); override;
  56. procedure g_stackframe_entry(list : taasmoutput;localsize : longint);override;
  57. procedure g_restore_frame_pointer(list : taasmoutput);override;
  58. procedure g_push_exception_value_reg(list : taasmoutput;reg : tregister);override;
  59. procedure g_push_exception_value_const(list : taasmoutput;reg : tregister);override;
  60. procedure g_pop_exception_value_reg(list : taasmoutput;reg : tregister);override;
  61. procedure g_return_from_proc(list : taasmoutput;parasize : aword); override;
  62. procedure a_loadaddress_ref_reg(list : taasmoutput;const ref : treference;r : tregister);override;
  63. procedure g_concatcopy(list : taasmoutput;const source,dest : treference;len : aword; delsource,loadref : boolean);override;
  64. function makeregsize(var reg: tregister; size: tcgsize): topsize; override;
  65. private
  66. procedure sizes2load(s1: tcgsize; s2: topsize; var op: tasmop; var s3: topsize);
  67. end;
  68. const
  69. TOpCG2AsmOp: Array[topcg] of TAsmOp = (A_ADD,A_AND,A_DIV,
  70. A_IDIV,A_MUL, A_IMUL, A_NEG,A_NOT,A_OR,
  71. A_SAR,A_SHL,A_SHR,A_SUB,A_XOR);
  72. TOpCmp2AsmCond: Array[topcmp] of TAsmCond = (C_NONE,C_E,C_G,
  73. C_L,C_GE,C_LE,C_NE,C_BE,C_B,C_AE,C_A);
  74. TCGSize2OpSize: Array[tcgsize] of topsize = (S_NO,S_B,S_W,S_L,S_L,
  75. S_B,S_W,S_L,S_L);
  76. implementation
  77. uses
  78. globtype,globals,verbose,systems,cutils,cga;
  79. { we implement the following routines because otherwise we can't }
  80. { instantiate the class since it's abstract }
  81. procedure tcg386.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;nr : longint);
  82. begin
  83. runerror(211);
  84. end;
  85. procedure tcg386.a_param_const(list : taasmoutput;size : tcgsize;a : aword;nr : longint);
  86. begin
  87. runerror(211);
  88. end;
  89. procedure tcg386.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;nr : longint);
  90. begin
  91. runerror(211);
  92. end;
  93. procedure tcg386.a_paramaddr_ref(list : taasmoutput;const r : treference;nr : longint);
  94. begin
  95. runerror(211);
  96. end;
  97. procedure tcg386.a_call_name(list : taasmoutput;const s : string;
  98. offset : longint);
  99. begin
  100. { how can we create asmsymbols which contain a name and an offset? }
  101. { (JM) }
  102. runerror(211);
  103. end;
  104. {********************** load instructions ********************}
  105. procedure tcg386.a_load_const_reg(list : taasmoutput; size: TCGSize; a : aword; reg : TRegister);
  106. begin
  107. { the optimizer will change it to "xor reg,reg" when loading zero, }
  108. { no need to do it here too (JM) }
  109. list.concat(taicpu.op_const_reg(A_MOV,TCGSize2OpSize[size],
  110. longint(a),reg))
  111. end;
  112. procedure tcg386.a_load_const_ref(list : taasmoutput; size: tcgsize; a : aword;const ref : treference);
  113. begin
  114. list.concat(taicpu.op_const_ref(A_MOV,TCGSize2OpSize[size],
  115. longint(a),newreference(ref)));
  116. end;
  117. procedure tcg386.a_load_reg_ref(list : taasmoutput; size: TCGSize; reg : tregister;const ref : treference);
  118. begin
  119. list.concat(taicpu.op_reg_ref(A_MOV,TCGSize2OpSize[size],reg,
  120. newreference(ref)));
  121. End;
  122. procedure tcg386.a_load_ref_reg(list : taasmoutput;size : tcgsize;const ref: treference;reg : tregister);
  123. var
  124. op: tasmop;
  125. s: topsize;
  126. begin
  127. if ref.is_immediate then
  128. a_load_const_reg(list,size,ref.offset,reg)
  129. else
  130. begin
  131. sizes2load(size,regsize(reg),op,s);
  132. list.concat(taicpu.op_ref_reg(op,s,newreference(ref),reg));
  133. end;
  134. end;
  135. procedure tcg386.a_load_reg_reg(list : taasmoutput;size : tcgsize;reg1,reg2 : tregister);
  136. var
  137. op: tasmop;
  138. s: topsize;
  139. begin
  140. sizes2load(size,regsize(reg1),op,s);
  141. if (reg1 = reg2) then
  142. { "mov reg1, reg1" doesn't make sense }
  143. if op = A_MOV then
  144. exit
  145. else if (op = A_MOVZX) then
  146. case size of
  147. OS_8:
  148. begin
  149. list.concat(taicpu.op_const_reg(A_AND,S_L,255,makereg32(reg1)));
  150. exit;
  151. end;
  152. OS_16:
  153. begin
  154. list.concat(taicpu.op_const_reg(A_AND,S_L,65535,reg2));
  155. exit;
  156. end;
  157. end;
  158. list.concat(taicpu.op_reg_reg(op,s,reg1,reg2));
  159. end;
  160. procedure tcg386.a_op_const_reg(list : taasmoutput; Op: TOpCG; a: AWord; reg: TRegister);
  161. var
  162. opcode: tasmop;
  163. power: longint;
  164. scratch_register: TRegister;
  165. begin
  166. Case Op of
  167. OP_DIV, OP_IDIV:
  168. Begin
  169. if ispowerof2(longint(a),power) then
  170. begin
  171. case op of
  172. OP_DIV:
  173. opcode := A_SHR;
  174. OP_IDIV:
  175. opcode := A_SAR;
  176. end;
  177. list.concat(taicpu.op_const_reg(opcode,regsize(reg),power,
  178. reg));
  179. exit;
  180. end;
  181. { the rest should be handled specifically in the code }
  182. { generator because of the silly register usage restraints }
  183. internalerror(200109224);
  184. End;
  185. OP_MUL,OP_IMUL:
  186. begin
  187. if not(cs_check_overflow in aktlocalswitches) and
  188. ispowerof2(longint(a),power) then
  189. begin
  190. list.concat(taicpu.op_const_reg(A_SHL,regsize(reg),power,
  191. reg));
  192. exit;
  193. end;
  194. if op = OP_IMUL then
  195. list.concat(taicpu.op_const_reg(A_IMUL,regsize(reg),
  196. longint(a),reg))
  197. else
  198. { OP_MUL should be handled specifically in the code }
  199. { generator because of the silly register usage restraints }
  200. internalerror(200109225);
  201. end;
  202. OP_ADD, OP_AND, OP_OR, OP_SUB, OP_XOR:
  203. if (a = 1) and
  204. (op in [OP_ADD,OP_SUB]) then
  205. if op = OP_ADD then
  206. list.concat(taicpu.op_reg(A_INC,regsize(reg),reg))
  207. else
  208. list.concat(taicpu.op_reg(A_DEC,regsize(reg),reg))
  209. else
  210. list.concat(taicpu.op_const_reg(TOpCG2AsmOp[op],regsize(reg),
  211. longint(a),reg));
  212. OP_SHL,OP_SHR,OP_SAR:
  213. begin
  214. if (a and 31) <> 0 Then
  215. list.concat(taicpu.op_const_reg(
  216. TOpCG2AsmOp[op],regsize(reg),a and 31,reg));
  217. if (a shr 5) <> 0 Then
  218. internalerror(68991);
  219. end
  220. else internalerror(68992);
  221. end;
  222. end;
  223. procedure tcg386.a_op_const_ref(list : taasmoutput; Op: TOpCG; size: TCGSize; a: AWord; const ref: TReference);
  224. var
  225. opcode: tasmop;
  226. power: longint;
  227. scratch_register: TRegister;
  228. begin
  229. Case Op of
  230. OP_DIV, OP_IDIV:
  231. Begin
  232. if ispowerof2(longint(a),power) then
  233. begin
  234. case op of
  235. OP_DIV:
  236. opcode := A_SHR;
  237. OP_IDIV:
  238. opcode := A_SAR;
  239. end;
  240. list.concat(taicpu.op_const_ref(opcode,
  241. TCgSize2OpSize[size],power,newreference(ref)));
  242. exit;
  243. end;
  244. { the rest should be handled specifically in the code }
  245. { generator because of the silly register usage restraints }
  246. internalerror(200109231);
  247. End;
  248. OP_MUL,OP_IMUL:
  249. begin
  250. if not(cs_check_overflow in aktlocalswitches) and
  251. ispowerof2(longint(a),power) then
  252. begin
  253. list.concat(taicpu.op_const_ref(A_SHL,TCgSize2OpSize[size],
  254. power,newreference(ref)));
  255. exit;
  256. end;
  257. { can't multiply a memory location directly with a constant }
  258. if op = OP_IMUL then
  259. inherited a_op_const_ref(list,op,size,a,ref)
  260. else
  261. { OP_MUL should be handled specifically in the code }
  262. { generator because of the silly register usage restraints }
  263. internalerror(200109232);
  264. end;
  265. OP_ADD, OP_AND, OP_OR, OP_SUB, OP_XOR:
  266. if (a = 1) and
  267. (op in [OP_ADD,OP_SUB]) then
  268. if op = OP_ADD then
  269. list.concat(taicpu.op_ref(A_INC,TCgSize2OpSize[size],
  270. newreference(ref)))
  271. else
  272. list.concat(taicpu.op_ref(A_DEC,TCgSize2OpSize[size],
  273. newreference(ref)))
  274. else
  275. list.concat(taicpu.op_const_ref(TOpCG2AsmOp[op],
  276. TCgSize2OpSize[size],longint(a),newreference(ref)));
  277. OP_SHL,OP_SHR,OP_SAR:
  278. begin
  279. if (a and 31) <> 0 Then
  280. list.concat(taicpu.op_const_ref(
  281. TOpCG2AsmOp[op],TCgSize2OpSize[size],a and 31,newreference(ref)));
  282. if (a shr 5) <> 0 Then
  283. internalerror(68991);
  284. end
  285. else internalerror(68992);
  286. end;
  287. end;
  288. procedure tcg386.a_op_reg_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; src, dst: TRegister);
  289. var
  290. dstsize: topsize;
  291. begin
  292. dstsize := makeregsize(dst,size);
  293. case op of
  294. OP_NEG,OP_NOT:
  295. begin
  296. list.concat(taicpu.op_reg(TOpCG2AsmOp[op],dstsize,dst));
  297. end;
  298. OP_MUL,OP_DIV,OP_IDIV:
  299. { special stuff, needs separate handling inside code }
  300. { generator }
  301. internalerror(200109233);
  302. else
  303. begin
  304. if regsize(src) <> dstsize then
  305. internalerror(200109226);
  306. list.concat(taicpu.op_reg_reg(TOpCG2AsmOp[op],dstsize,
  307. src,dst));
  308. end;
  309. end;
  310. end;
  311. procedure tcg386.a_op_ref_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; const ref: TReference; reg: TRegister);
  312. var
  313. opsize: topsize;
  314. begin
  315. if ref.is_immediate then
  316. a_op_const_reg(list,op,ref.offset,reg)
  317. else
  318. begin
  319. case op of
  320. OP_NEG,OP_NOT,OP_IMUL:
  321. begin
  322. inherited a_op_ref_reg(list,op,size,ref,reg);
  323. end;
  324. OP_MUL,OP_DIV,OP_IDIV:
  325. { special stuff, needs separate handling inside code }
  326. { generator }
  327. internalerror(200109239);
  328. else
  329. begin
  330. opsize := makeregsize(reg,size);
  331. list.concat(taicpu.op_ref_reg(TOpCG2AsmOp[op],opsize,
  332. newreference(ref),reg));
  333. end;
  334. end;
  335. end;
  336. end;
  337. procedure tcg386.a_op_reg_ref(list : taasmoutput; Op: TOpCG; size: TCGSize;reg: TRegister; const ref: TReference);
  338. var
  339. opsize: topsize;
  340. begin
  341. case op of
  342. OP_NEG,OP_NOT:
  343. begin
  344. if reg <> R_NO then
  345. internalerror(200109237);
  346. list.concat(taicpu.op_ref(TOpCG2AsmOp[op],tcgsize2opsize[size],
  347. newreference(ref)));
  348. end;
  349. OP_IMUL:
  350. begin
  351. { this one needs a load/imul/store, which is the default }
  352. inherited a_op_ref_reg(list,op,size,ref,reg);
  353. end;
  354. OP_MUL,OP_DIV,OP_IDIV:
  355. { special stuff, needs separate handling inside code }
  356. { generator }
  357. internalerror(200109238);
  358. else
  359. begin
  360. opsize := tcgsize2opsize[size];
  361. list.concat(taicpu.op_reg_ref(TOpCG2AsmOp[op],opsize,reg,
  362. newreference(ref)));
  363. end;
  364. end;
  365. end;
  366. {*************** compare instructructions ****************}
  367. procedure tcg386.a_cmp_const_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;reg : tregister;
  368. l : tasmlabel);
  369. begin
  370. if a <> 0 then
  371. list.concat(taicpu.op_const_reg(A_CMP,regsize(reg),longint(a),
  372. reg))
  373. else
  374. list.concat(taicpu.op_reg_reg(A_TEST,regsize(reg),reg,reg));
  375. a_jmp_cond(list,cmp_op,l);
  376. end;
  377. procedure tcg386.a_cmp_const_ref_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;const ref : treference;
  378. l : tasmlabel);
  379. begin
  380. list.concat(taicpu.op_const_ref(A_CMP,TCgSize2OpSize[size],
  381. longint(a),newreference(ref)));
  382. a_jmp_cond(list,cmp_op,l);
  383. end;
  384. procedure tcg386.a_cmp_reg_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;
  385. reg1,reg2 : tregister;l : tasmlabel);
  386. begin
  387. if regsize(reg1) <> regsize(reg2) then
  388. internalerror(200109226);
  389. list.concat(taicpu.op_reg_reg(A_CMP,regsize(reg1),reg1,reg2));
  390. a_jmp_cond(list,cmp_op,l);
  391. end;
  392. procedure tcg386.a_cmp_ref_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;const ref: treference; reg : tregister;l : tasmlabel);
  393. var
  394. opsize: topsize;
  395. begin
  396. opsize := makeregsize(reg,size);
  397. list.concat(taicpu.op_ref_reg(A_CMP,opsize,newreference(ref),reg));
  398. a_jmp_cond(list,cmp_op,l);
  399. end;
  400. procedure tcg386.a_jmp_cond(list : taasmoutput;cond : TOpCmp;l: tasmlabel);
  401. var
  402. ai : taicpu;
  403. begin
  404. if cond=OC_None then
  405. ai := Taicpu.Op_sym(A_JMP,S_NO,l)
  406. else
  407. begin
  408. ai:=Taicpu.Op_sym(A_Jcc,S_NO,l);
  409. ai.SetCondition(TOpCmp2AsmCond[cond]);
  410. end;
  411. ai.is_jmp:=true;
  412. list.concat(ai);
  413. end;
  414. procedure tcg386.g_flags2reg(list: taasmoutput; const f: tresflags; reg: TRegister);
  415. var
  416. ai : taicpu;
  417. hreg : tregister;
  418. begin
  419. hreg := makereg8(reg);
  420. ai:=Taicpu.Op_reg(A_Setcc,S_B,hreg);
  421. ai.SetCondition(flag_2_cond[f]);
  422. list.concat(ai);
  423. if hreg<>reg then
  424. begin
  425. if reg in regset16bit then
  426. emit_to_reg16(hreg)
  427. else
  428. emit_to_reg32(hreg);
  429. end;
  430. end;
  431. { *********** entry/exit code and address loading ************ }
  432. procedure tcg386.g_stackframe_entry(list : taasmoutput;localsize : longint);
  433. begin
  434. runerror(211);
  435. end;
  436. procedure tcg386.g_restore_frame_pointer(list : taasmoutput);
  437. begin
  438. runerror(211);
  439. end;
  440. procedure tcg386.g_push_exception_value_reg(list : taasmoutput;reg : tregister);
  441. begin
  442. runerror(211);
  443. end;
  444. procedure tcg386.g_push_exception_value_const(list : taasmoutput;reg : tregister);
  445. begin
  446. runerror(211);
  447. end;
  448. procedure tcg386.g_pop_exception_value_reg(list : taasmoutput;reg : tregister);
  449. begin
  450. runerror(211);
  451. end;
  452. procedure tcg386.g_return_from_proc(list : taasmoutput;parasize : aword);
  453. begin
  454. runerror(211);
  455. end;
  456. procedure tcg386.a_loadaddress_ref_reg(list : taasmoutput;const ref : treference;r : tregister);
  457. begin
  458. list.concat(taicpu.op_ref_reg(A_LEA,S_L,newreference(ref),r));
  459. end;
  460. function tcg386.makeregsize(var reg: tregister; size: tcgsize): topsize;
  461. begin
  462. { this function only allows downsizing a register, because otherwise }
  463. { we may start working with garbage (JM) }
  464. case size of
  465. OS_32,OS_S32:
  466. begin
  467. if not (reg in [R_EAX..R_EDI]) then
  468. internalerror(2001092313);
  469. result := S_L;
  470. end;
  471. OS_8,OS_S8:
  472. begin
  473. reg := makereg8(reg);
  474. result := S_B;
  475. end;
  476. OS_16,OS_S16:
  477. begin
  478. if reg in [R_AL..R_BH] then
  479. internalerror(2001092314);
  480. reg := makereg16(reg);
  481. result := S_W;
  482. end;
  483. else
  484. internalerror(2001092312);
  485. end;
  486. end;
  487. { ************* concatcopy ************ }
  488. procedure tcg386.g_concatcopy(list : taasmoutput;const source,dest : treference;len : aword; delsource,loadref : boolean);
  489. { temp implementation, until it's permanenty moved here from cga.pas }
  490. var
  491. oldlist: taasmoutput;
  492. begin
  493. if list <> exprasmlist then
  494. begin
  495. oldlist := exprasmlist;
  496. exprasmlist := list;
  497. end;
  498. cga.concatcopy(source,dest,len,delsource,loadref);
  499. if list <> exprasmlist then
  500. list := oldlist;
  501. end;
  502. {***************** This is private property, keep out! :) *****************}
  503. procedure tcg386.sizes2load(s1: tcgsize; s2: topsize; var op: tasmop; var s3: topsize);
  504. begin
  505. case s2 of
  506. S_B:
  507. if S1 in [OS_8,OS_S8] then
  508. s3 := S_B
  509. else internalerror(200109221);
  510. S_W:
  511. case s1 of
  512. OS_8,OS_S8:
  513. s3 := S_BW;
  514. OS_16,OS_S16:
  515. s3 := S_W;
  516. else internalerror(200109222);
  517. end;
  518. S_L:
  519. case s1 of
  520. OS_8,OS_S8:
  521. s3 := S_BL;
  522. OS_16,OS_S16:
  523. s3 := S_WL;
  524. OS_32,OS_S32:
  525. s3 := S_L;
  526. else internalerror(200109223);
  527. end;
  528. else internalerror(200109227);
  529. end;
  530. if s3 in [S_B,S_W,S_L] then
  531. op := A_MOV
  532. else if s1 in [OS_8,OS_16,OS_32] then
  533. op := A_MOVZX
  534. else
  535. op := A_MOVSX;
  536. end;
  537. begin
  538. cg := tcg386.create;
  539. end.
  540. {
  541. $Log$
  542. Revision 1.1 2001-09-28 20:39:33 jonas
  543. * changed all flow control structures (except for exception handling
  544. related things) to processor independent code (in new ncgflw unit)
  545. + generic cgobj unit which contains lots of code generator helpers with
  546. global "cg" class instance variable
  547. + cgcpu unit for i386 (implements processor specific routines of the above
  548. unit)
  549. * updated cgbase and cpubase for the new code generator units
  550. * include ncgflw unit in cpunode unit
  551. }