source: dev/trunk/abdev/BasicCompiler64/stack_frame.cpp@ 226

Last change on this file since 226 was 226, checked in by dai_9181, 17 years ago
File size: 3.7 KB
Line 
1#include "stdafx.h"
2
3#include <Compiler.h>
4
5#include "../BasicCompiler_Common/common.h"
6#include "Opcode.h"
7
8
9/////////////////////////
10// スタックフレーム管理
11/////////////////////////
12
13CStackFrame::CStackFrame(){
14 lowest_sp=0;
15 now_sp=0;
16 max_parm_size=0;
17}
18CStackFrame::~CStackFrame(){
19 //オブジェクト破棄時に不整合がないかをチェック(バグ回避)
20 error_check();
21}
22int CStackFrame::GetFrameSize( int localParamSize ){
23 int answer_sp;
24
25 answer_sp=lowest_sp-max_parm_size;
26
27 if((localParamSize%0x10)){
28 if((answer_sp%0x10)==0){
29 //関数のエントリポイントで128ビット境界ラインに合わせるため
30 return -(answer_sp-0x08);
31 }
32 return -(answer_sp-0x10);
33 }
34
35 if((answer_sp%0x10)==0){
36 //関数のエントリポイントで128ビット境界ラインに合わせるため
37 return -(answer_sp-0x10);
38 }
39 return -(answer_sp-0x08);
40}
41int CStackFrame::GetNowSp(){
42 return now_sp;
43}
44void CStackFrame::mov_sp( int reg ){
45 //mov reg,rsp
46 compiler.codeGenerator.op_mov_RR( reg, REG_RSP );
47
48 //add reg,now_sp
49 compiler.codeGenerator.op_add_RV( reg, now_sp );
50
51 //スケジュールをセット
52 obp-=sizeof(long);
53 add();
54 obp+=sizeof(long);
55}
56int CStackFrame::push(int reg){
57 now_sp-=sizeof(_int64);
58 if(lowest_sp>now_sp) lowest_sp=now_sp;
59
60 if(reg==REG_NON) return now_sp;
61
62 //mov qword ptr[rsp+offset],reg
63 compiler.codeGenerator.op_mov_MR(sizeof(_int64),reg,REG_RSP,now_sp,MOD_BASE_DISP32);
64
65 //スケジュールをセット
66 obp-=sizeof(long);
67 add();
68 obp+=sizeof(long);
69
70 return now_sp;
71}
72void CStackFrame::push(int xmm_reg,int varSize){
73 now_sp-=sizeof(_int64);
74 if(lowest_sp>now_sp) lowest_sp=now_sp;
75
76 if(varSize==sizeof(double)){
77 //movlpd qword ptr[rsp+offset],xmm_reg
78 compiler.codeGenerator.op_movlpd_MR(xmm_reg,REG_RSP,now_sp,MOD_BASE_DISP32);
79 }
80 if(varSize==sizeof(float)){
81 //movss dword ptr[rsp+offset],xmm_reg
82 OpBuffer[obp++]=(char)0xF3;
83 OpBuffer[obp++]=(char)0x0F;
84 OpBuffer[obp++]=(char)0x11;
85 OpBuffer[obp++]=(char)(0x84| REGISTER_OPERAND(xmm_reg)<<3 );
86 OpBuffer[obp++]=(char)0x24;
87 *((long *)(OpBuffer+obp))=now_sp;
88 obp+=sizeof(long);
89 }
90
91 //スケジュールをセット
92 obp-=sizeof(long);
93 add();
94 obp+=sizeof(long);
95}
96void CStackFrame::ref_offset_data( int reg, int sp_offset ){
97 //mov reg,qword ptr[rsp+offset] ※スタックフレームを利用
98 compiler.codeGenerator.op_mov_RM(sizeof(_int64),reg,REG_RSP,sp_offset,MOD_BASE_DISP32);
99
100 //スケジュールをセット
101 obp-=sizeof(long);
102 add();
103 obp+=sizeof(long);
104}
105void CStackFrame::ref(int reg){
106 ref_offset_data( reg, now_sp );
107}
108void CStackFrame::ref(int xmm_reg,int varSize){
109 if(varSize==sizeof(double)){
110 //movlpd xmm_reg,qword ptr[rsp+offset]
111 compiler.codeGenerator.op_movlpd_RM(xmm_reg,REG_RSP,now_sp,MOD_BASE_DISP32);
112 }
113 if(varSize==sizeof(float)){
114 //movss xmm_reg,dword ptr[rsp+offset]
115 OpBuffer[obp++]=(char)0xF3;
116 OpBuffer[obp++]=(char)0x0F;
117 OpBuffer[obp++]=(char)0x10;
118 OpBuffer[obp++]=(char)(0x84| REGISTER_OPERAND(xmm_reg)<<3 );
119 OpBuffer[obp++]=(char)0x24;
120 *((long *)(OpBuffer+obp))=now_sp;
121 obp+=sizeof(long);
122 }
123
124 //スケジュールをセット
125 obp-=sizeof(long);
126 add();
127 obp+=sizeof(long);
128}
129void CStackFrame::pop(int reg){
130 if(reg!=REG_NON) ref(reg);
131
132 now_sp+=sizeof(_int64);
133}
134void CStackFrame::pop(int xmm_reg,int varSize){
135 ref(xmm_reg,varSize);
136
137 now_sp+=sizeof(_int64);
138}
139void CStackFrame::parameter_allocate(int size){
140 if(max_parm_size<size) max_parm_size=size;
141}
142void CStackFrame::RunningSchedule( int stackFrameSize ){
143 for(int i=0;i<num;i++){
144 *((long *)(OpBuffer+pObpValues[i])) += stackFrameSize;
145 }
146}
147
148void CStackFrame::error_check(){
149 if(now_sp){
150 SetError(300,NULL,cp);
151 }
152}
153
154//スタックフレーム管理用オブジェクトポインタ
155CStackFrame *pobj_sf;
Note: See TracBrowser for help on using the repository browser.