PageRenderTime 141ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/tpl/include/tpl/emu/CPU.h

http://winx.googlecode.com/
C Header | 477 lines | 354 code | 93 blank | 30 comment | 2 complexity | a2e02e1a41ff13ce85ba853e41bcf3a8 MD5 | raw file
  1. /* -------------------------------------------------------------------------
  2. // WINX: a C++ template GUI library - MOST SIMPLE BUT EFFECTIVE
  3. //
  4. // This file is a part of the WINX Library.
  5. // The use and distribution terms for this software are covered by the
  6. // Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
  7. // which can be found in the file CPL.txt at this distribution. By using
  8. // this software in any fashion, you are agreeing to be bound by the terms
  9. // of this license. You must not remove this notice, or any other, from
  10. // this software.
  11. //
  12. // Module: tpl/emu/CPU.h
  13. // Creator: xushiwei
  14. // Email: xushiweizh@gmail.com
  15. // Date: 2006-8-13 9:41:58
  16. //
  17. // $Id: CPU.h 588 2008-05-28 07:22:04Z xushiweizh $
  18. // -----------------------------------------------------------------------*/
  19. #ifndef TPL_EMU_CPU_H
  20. #define TPL_EMU_CPU_H
  21. #ifndef TPL_EMU_CODE_H
  22. #include "Code.h"
  23. #endif
  24. #ifndef TPL_EMU_LABEL_H
  25. #include "Label.h"
  26. #endif
  27. #ifndef TPL_EMU_VAR_H
  28. #include "Var.h"
  29. #endif
  30. #if defined(TPL_EMU_BACKWARD)
  31. #include "_OldVar.h"
  32. #else
  33. #define TPL_EMU_OLDVAR_INSTRS_()
  34. #endif
  35. #if !defined(_FUNCTIONAL_) && !defined(_GLIBCXX_FUNCTIONAL) && !defined(_FUNCTIONAL)
  36. #include <functional>
  37. #endif
  38. NS_TPL_EMU_BEGIN
  39. // =========================================================================
  40. // class policy::Default
  41. namespace policy
  42. {
  43. template <bool bDebug>
  44. class Default
  45. {
  46. public:
  47. typedef DefaultAllocator alloc_type;
  48. typedef Context<void, bDebug> execute_context;
  49. };
  50. template <bool bDebug>
  51. class ExtDefault : public Default<bDebug>
  52. {
  53. public:
  54. typedef Context<DefaultAllocator, bDebug> execute_context;
  55. };
  56. }
  57. // =========================================================================
  58. // class Assign/ExtAssign
  59. template <class ValT>
  60. class Assign : public std::binary_function<ValT, ValT, ValT>
  61. {
  62. public:
  63. ValT TPL_CALL operator()(const ValT& x, const ValT& y) const {
  64. return variant_to_ref(x) = y;
  65. }
  66. };
  67. template <class ValT>
  68. class ExtAssign : public std::binary_function<ValT, ValT, ValT>
  69. {
  70. public:
  71. template <class AllocT>
  72. ValT TPL_CALL operator()(AllocT& alloc, const ValT& x, const ValT& y) const {
  73. return ext_assign(alloc, variant_to_ref(x), y);
  74. }
  75. };
  76. // =========================================================================
  77. // class CPU
  78. template <class ValT, bool bDebug = false, class PolicyT = policy::Default<bDebug> >
  79. class CPU
  80. {
  81. private:
  82. typedef typename PolicyT::alloc_type AllocT;
  83. typedef typename PolicyT::execute_context ExecuteContextT;
  84. typedef Code<ValT, ExecuteContextT, AllocT> CodeT;
  85. public:
  86. typedef AllocT alloc_type;
  87. typedef CodeT code_type;
  88. typedef CodeContext code_context;
  89. typedef ExecuteContextT execute_context;
  90. typedef typename CodeT::stack_type stack_type;
  91. typedef typename CodeT::instruction_type instruction_type;
  92. private:
  93. typedef stack_type StackT;
  94. typedef execute_context ContextT;
  95. typedef instruction_type InstructionT;
  96. typedef Variable VarT;
  97. public:
  98. typedef VarT var_type;
  99. template <size_t n = TPL_EMU_DYNAMIC_LABEL>
  100. class label_type : public Label<n> {
  101. };
  102. template <size_t n = TPL_EMU_DYNAMIC_LABEL>
  103. class proc_type : public Label<n> {
  104. };
  105. template <size_t n>
  106. static CodeGenerator<LabelDefine<Label<n> > > TPL_CALL label(Label<n>& label_) {
  107. return CodeGenerator<LabelDefine<Label<n> > >(label_);
  108. }
  109. template <size_t n>
  110. static CodeGenerator<ProcDefine<Label<n> > > TPL_CALL proc(Label<n>& proc_) {
  111. return CodeGenerator<ProcDefine<Label<n> > >(proc_);
  112. }
  113. template <size_t n>
  114. static CodeGenerator<Proc1Arg<Label<n> > > TPL_CALL proc(Label<n>& proc_, VarT& var_) {
  115. return Proc1Arg<Label<n> >(proc_, var_);
  116. }
  117. template <size_t n>
  118. static CodeGenerator<Proc2Arg<Label<n> > > TPL_CALL proc(Label<n>& proc_, VarT& var_, VarT& var2_) {
  119. return Proc2Arg<Label<n> >(proc_, var_, var2_);
  120. }
  121. template <size_t n>
  122. static CodeGenerator<Proc3Arg<Label<n> > > TPL_CALL proc(Label<n>& proc_, VarT& var_, VarT& var2_, VarT& var3_) {
  123. return Proc3Arg<Label<n> >(proc_, var_, var2_, var3_);
  124. }
  125. template <size_t n>
  126. static CodeGenerator<Proc4Arg<Label<n> > > TPL_CALL proc(
  127. Label<n>& proc_, VarT& var_, VarT& var2_, VarT& var3_, VarT& var4_) {
  128. return Proc4Arg<Label<n> >(proc_, var_, var2_, var3_, var4_);
  129. }
  130. template <size_t n>
  131. static CodeGenerator<Proc5Arg<Label<n> > > TPL_CALL proc(
  132. Label<n>& proc_, VarT& var_, VarT& var2_, VarT& var3_, VarT& var4_, VarT& var5_) {
  133. return Proc5Arg<Label<n> >(proc_, var_, var2_, var3_, var4_, var5_);
  134. }
  135. template <size_t n>
  136. static CodeGenerator<Proc6Arg<Label<n> > > TPL_CALL proc(
  137. Label<n>& proc_, VarT& var_, VarT& var2_, VarT& var3_, VarT& var4_, VarT& var5_, VarT& var6_) {
  138. return Proc6Arg<Label<n> >(proc_, var_, var2_, var3_, var4_, var5_, var6_);
  139. }
  140. #define TPL_EMU_LABEL_REF_(op, InstrT) \
  141. template <size_t n> \
  142. static CodeGenerator<LabelRefer<Label<n>, InstrT<StackT, ContextT> > > TPL_CALL op(Label<n>& label_) { \
  143. return CodeGenerator<LabelRefer<Label<n>, InstrT<StackT, ContextT> > >(label_); \
  144. }
  145. TPL_EMU_LABEL_REF_(call, Call)
  146. TPL_EMU_LABEL_REF_(jmp, Jmp)
  147. TPL_EMU_LABEL_REF_(jz, JmpIfFalse)
  148. public:
  149. template <template <class Type> class Op_>
  150. static InstructionT TPL_CALL op() {
  151. return OpInstr<Op_, StackT, ContextT>::instr();
  152. }
  153. #define TPL_EMU_OP_(op, op_) \
  154. static InstructionT TPL_CALL op() { \
  155. return OpInstr<op_, StackT, ContextT>::instr(); \
  156. }
  157. TPL_EMU_OP_(add, std::plus)
  158. TPL_EMU_OP_(sub, std::minus)
  159. TPL_EMU_OP_(mul, std::multiplies)
  160. TPL_EMU_OP_(div, std::divides)
  161. TPL_EMU_OP_(mod, std::modulus)
  162. TPL_EMU_OP_(assign, Assign)
  163. TPL_EMU_OP_(neg, std::negate)
  164. TPL_EMU_OP_(eq, std::equal_to)
  165. TPL_EMU_OP_(ne, std::not_equal_to)
  166. TPL_EMU_OP_(gt, std::greater)
  167. TPL_EMU_OP_(ge, std::greater_equal)
  168. TPL_EMU_OP_(lt, std::less)
  169. TPL_EMU_OP_(le, std::less_equal)
  170. #define TPL_EMU_FN_IMPL_(n) \
  171. static InstructionT TPL_CALL func(typename FnInstr<n, StackT, ContextT>::op_type fn) { \
  172. return FnInstr<n, StackT, ContextT>::instr(fn); \
  173. }
  174. TPL_EMU_FN_IMPL_(1)
  175. TPL_EMU_FN_IMPL_(2)
  176. TPL_EMU_FN_IMPL_(3)
  177. TPL_EMU_FN_IMPL_(4)
  178. TPL_EMU_FN_IMPL_(5)
  179. TPL_EMU_FN_IMPL_(6)
  180. #define TPL_EMU_VARGS_IMPL_(IntT) \
  181. static InstructionT TPL_CALL func(typename VargsFnInstr<IntT, StackT, ContextT>::op_type fn) { \
  182. return VargsFnInstr<IntT, StackT, ContextT>::instr(fn); \
  183. }
  184. TPL_EMU_VARGS_IMPL_(size_t)
  185. TPL_EMU_VARGS_IMPL_(int)
  186. TPL_EMU_OLDVAR_INSTRS_()
  187. public:
  188. static InstructionT TPL_CALL nop() {
  189. return Nop<StackT, ContextT>::instr();
  190. }
  191. static InstructionT TPL_CALL add(ptrdiff_t val) {
  192. return Add<StackT, ContextT>::instr(val);
  193. }
  194. static InstructionT TPL_CALL sub(ptrdiff_t val) {
  195. return Add<StackT, ContextT>::instr(-val);
  196. }
  197. static InstructionT TPL_CALL inc(ptrdiff_t val = 1) {
  198. return Inc<StackT, ContextT>::instr(val);
  199. }
  200. static InstructionT TPL_CALL dec(ptrdiff_t val = 1) {
  201. return Inc<StackT, ContextT>::instr(-val);
  202. }
  203. template <class ValT2>
  204. static CodeGenerator<InstrCode<ValT2, Push<StackT, ContextT> > > TPL_CALL push(const ValT2& val) {
  205. return CodeGenerator<InstrCode<ValT2, Push<StackT, ContextT> > >(val);
  206. }
  207. template <class AllocT2, class ValT2>
  208. static InstructionT TPL_CALL push(AllocT2& alloc, const ValT2& val) {
  209. return Push<StackT, ContextT>::instr(alloc, val);
  210. }
  211. template <class ValT2>
  212. static CodeGenerator<InstrCode<ValT2, Repush<StackT, ContextT> > > TPL_CALL repush(const ValT2& val) {
  213. return CodeGenerator<InstrCode<ValT2, Repush<StackT, ContextT> > >(val);
  214. }
  215. template <class AllocT2, class ValT2>
  216. static InstructionT TPL_CALL repush(AllocT2& alloc, const ValT2& val) {
  217. return Repush<StackT, ContextT>::instr(alloc, val);
  218. }
  219. static InstructionT TPL_CALL pop(size_t n) {
  220. return Pop<StackT, ContextT>::instr(n);
  221. }
  222. static InstructionT TPL_CALL pop() {
  223. return Pop<StackT, ContextT>::instr();
  224. }
  225. static InstructionT TPL_CALL arity(size_t n) {
  226. return Arity<StackT, ContextT>::instr(n);
  227. }
  228. static InstructionT TPL_CALL ret(size_t n) {
  229. return RetN<StackT, ContextT>::instr(n);
  230. }
  231. static InstructionT TPL_CALL ret() {
  232. return Ret<StackT, ContextT>::instr();
  233. }
  234. static InstructionT TPL_CALL push_vargs() {
  235. return PushVArgs<StackT, ContextT>::instr();
  236. }
  237. static InstructionT TPL_CALL lea_vargs() {
  238. return PushVArgs<StackT, ContextT>::instr();
  239. }
  240. public:
  241. static CodeGenerator<VarOp<PushVar<StackT, ContextT> > > TPL_CALL push(const VarT& var_) {
  242. return CodeGenerator<VarOp<PushVar<StackT, ContextT> > >(var_);
  243. }
  244. static CodeGenerator<VarOp<LeaVar<StackT, ContextT> > > TPL_CALL lea(const VarT& var_) {
  245. return CodeGenerator<VarOp<LeaVar<StackT, ContextT> > >(var_);
  246. }
  247. static CodeGenerator<VarOp<AssignVar<StackT, ContextT> > > TPL_CALL assign(const VarT& var_) {
  248. return CodeGenerator<VarOp<AssignVar<StackT, ContextT> > >(var_);
  249. }
  250. static CodeGenerator<DefineArg> TPL_CALL arg(VarT& var_) {
  251. return CodeGenerator<DefineArg>(var_);
  252. }
  253. static CodeGenerator<EndArgList> TPL_CALL end_arglist() {
  254. return CodeGenerator<EndArgList>();
  255. }
  256. static CodeGenerator<VarInit> TPL_CALL var_init(VarT& var_) {
  257. return CodeGenerator<VarInit>(var_);
  258. }
  259. static CodeGenerator<DefineVar> TPL_CALL var(VarT& var_) {
  260. return DefineVar(var_);
  261. }
  262. static CodeGenerator<Define2Var> TPL_CALL var(VarT& var_, VarT& var2_) {
  263. return Define2Var(var_, var2_);
  264. }
  265. static CodeGenerator<Define3Var> TPL_CALL var(VarT& var_, VarT& var2_, VarT& var3_) {
  266. return Define3Var(var_, var2_, var3_);
  267. }
  268. static CodeGenerator<Define4Var> TPL_CALL var(VarT& var_, VarT& var2_, VarT& var3_, VarT& var4_) {
  269. return Define4Var(var_, var2_, var3_, var4_);
  270. }
  271. static CodeGenerator<Define5Var> TPL_CALL var(VarT& var_, VarT& var2_, VarT& var3_, VarT& var4_, VarT& var5_) {
  272. return Define5Var(var_, var2_, var3_, var4_, var5_);
  273. }
  274. static CodeGenerator<Define6Var> TPL_CALL var(VarT& var_, VarT& var2_, VarT& var3_, VarT& var4_, VarT& var5_, VarT& var6_) {
  275. return Define6Var(var_, var2_, var3_, var4_, var5_, var6_);
  276. }
  277. };
  278. // =========================================================================
  279. // ExtCPU: ext-operators
  280. #define TPL_EMU_BINARY_EXTOP_(op) \
  281. template <class ValT> \
  282. class op : public std::binary_function<ValT, ValT, ValT> \
  283. { \
  284. public: \
  285. template <class AllocT> \
  286. ValT TPL_CALL operator()(AllocT& alloc, const ValT& x, const ValT& y) const { \
  287. return ext_##op(alloc, x, y); \
  288. } \
  289. };
  290. TPL_EMU_BINARY_EXTOP_(plus)
  291. TPL_EMU_BINARY_EXTOP_(minus)
  292. TPL_EMU_BINARY_EXTOP_(multiplies)
  293. TPL_EMU_BINARY_EXTOP_(divides)
  294. TPL_EMU_BINARY_EXTOP_(modulus)
  295. TPL_EMU_BINARY_EXTOP_(equal_to)
  296. TPL_EMU_BINARY_EXTOP_(not_equal_to)
  297. TPL_EMU_BINARY_EXTOP_(greater)
  298. TPL_EMU_BINARY_EXTOP_(greater_equal)
  299. TPL_EMU_BINARY_EXTOP_(less)
  300. TPL_EMU_BINARY_EXTOP_(less_equal)
  301. #define TPL_EMU_UNARY_EXTOP_(op) \
  302. template <class ValT> \
  303. class op : public std::unary_function<ValT, ValT> \
  304. { \
  305. public: \
  306. template <class AllocT> \
  307. ValT TPL_CALL operator()(AllocT& alloc, const ValT& x) const { \
  308. return ext_##op(alloc, x); \
  309. } \
  310. };
  311. TPL_EMU_UNARY_EXTOP_(negate)
  312. // -------------------------------------------------------------------------
  313. // class ExtCPU
  314. template <class ValT, bool bDebug = false, class PolicyT = policy::ExtDefault<bDebug> >
  315. class ExtCPU : public CPU<ValT, bDebug, PolicyT>
  316. {
  317. private:
  318. typedef CPU<ValT, bDebug, PolicyT> Base;
  319. typedef typename Base::instruction_type InstructionT;
  320. typedef typename Base::stack_type StackT;
  321. typedef typename Base::execute_context ContextT;
  322. typedef typename Base::var_type VarT;
  323. public:
  324. using Base::func;
  325. template <template <class Type> class Op_>
  326. static InstructionT TPL_CALL ext_op() {
  327. return ExtOpInstr<Op_, StackT, ContextT>::instr();
  328. }
  329. #define TPL_EMU_EXTOP_(op, op_) \
  330. static InstructionT TPL_CALL op() { \
  331. return ExtOpInstr<op_, StackT, ContextT>::instr(); \
  332. }
  333. TPL_EMU_EXTOP_(add, NS_TPL_EMU::plus)
  334. TPL_EMU_EXTOP_(sub, NS_TPL_EMU::minus)
  335. TPL_EMU_EXTOP_(mul, NS_TPL_EMU::multiplies)
  336. TPL_EMU_EXTOP_(div, NS_TPL_EMU::divides)
  337. TPL_EMU_EXTOP_(mod, NS_TPL_EMU::modulus)
  338. TPL_EMU_EXTOP_(assign, ExtAssign)
  339. TPL_EMU_EXTOP_(neg, NS_TPL_EMU::negate)
  340. TPL_EMU_EXTOP_(eq, NS_TPL_EMU::equal_to)
  341. TPL_EMU_EXTOP_(ne, NS_TPL_EMU::not_equal_to)
  342. TPL_EMU_EXTOP_(gt, NS_TPL_EMU::greater)
  343. TPL_EMU_EXTOP_(ge, NS_TPL_EMU::greater_equal)
  344. TPL_EMU_EXTOP_(lt, NS_TPL_EMU::less)
  345. TPL_EMU_EXTOP_(le, NS_TPL_EMU::less_equal)
  346. #define TPL_EMU_EXTFN_IMPL_(n) \
  347. static InstructionT TPL_CALL func(typename ExtFnInstr<n, StackT, ContextT>::op_type fn) { \
  348. return ExtFnInstr<n, StackT, ContextT>::instr(fn); \
  349. }
  350. TPL_EMU_EXTFN_IMPL_(1)
  351. TPL_EMU_EXTFN_IMPL_(2)
  352. TPL_EMU_EXTFN_IMPL_(3)
  353. TPL_EMU_EXTFN_IMPL_(4)
  354. TPL_EMU_EXTFN_IMPL_(5)
  355. TPL_EMU_EXTFN_IMPL_(6)
  356. #define TPL_EMU_EXTVARGS_IMPL_(IntT) \
  357. static InstructionT TPL_CALL func(typename ExtVargsFnInstr<IntT, StackT, ContextT>::op_type fn) { \
  358. return ExtVargsFnInstr<IntT, StackT, ContextT>::instr(fn); \
  359. }
  360. TPL_EMU_EXTVARGS_IMPL_(size_t)
  361. TPL_EMU_EXTVARGS_IMPL_(int)
  362. public:
  363. static CodeGenerator<VarOp<PushVar<StackT, ContextT> > > TPL_CALL push(const VarT& var_) {
  364. return CodeGenerator<VarOp<PushVar<StackT, ContextT> > >(var_);
  365. }
  366. template <class ValT2>
  367. static CodeGenerator<ExtInstrCode<ValT2, Push<StackT, ContextT>, ValT> > TPL_CALL push(const ValT2& val) {
  368. return CodeGenerator<ExtInstrCode<ValT2, Push<StackT, ContextT>, ValT> >(val);
  369. }
  370. static CodeGenerator<InstrCode<ValT, Push<StackT, ContextT> > > TPL_CALL push(const ValT& val) {
  371. return CodeGenerator<InstrCode<ValT, Push<StackT, ContextT> > >(val);
  372. }
  373. template <class ValT2>
  374. static CodeGenerator<ExtInstrCode<ValT2, Repush<StackT, ContextT>, ValT> > TPL_CALL repush(const ValT2& val) {
  375. return CodeGenerator<ExtInstrCode<ValT2, Repush<StackT, ContextT>, ValT> >(val);
  376. }
  377. static CodeGenerator<InstrCode<ValT, Repush<StackT, ContextT> > > TPL_CALL repush(const ValT& val) {
  378. return CodeGenerator<InstrCode<ValT, Repush<StackT, ContextT> > >(val);
  379. }
  380. };
  381. // =========================================================================
  382. // $Log: $
  383. NS_TPL_EMU_END
  384. #endif /* TPL_EMU_CPU_H */