32
32
WriteInstruction(X86_PUSH,&p1);
35
void CELFOutput::WritePushFloatInstruction(float)
35
void CELFOutput::WritePushFloatInstruction(float fVal)
37
// To push a float onto the stack, we have to
38
// register the constant in the float literal
39
// list and then push the two parts of it
42
const char * pName = RegisterFloatLiteral(fVal).c_str();
44
// Now we simply push the value returned
45
// using two push instructions
47
CInstructionParameter p1;
48
p1.iType = PT_DWORD_SYMBOL_4;
49
p1.value.pString = pName;
51
WriteInstruction(X86_PUSH,&p1);
53
p1.iType = PT_DWORD_SYMBOL;
55
WriteInstruction(X86_PUSH,&p1);
40
58
void CELFOutput::WritePushStringInstruction(std::string str)
61
79
if(pSrc->type->iType == VT_FLOAT)
63
// TODO: unimplemented
81
CInstructionParameter p1;
82
p1.iType = PT_DWORD_VALUE_4;
83
p1.value.iOffset = pSrc->offset;
85
WriteInstruction(X86_PUSH,&p1);
87
p1.iType = PT_DWORD_VALUE;
89
WriteInstruction(X86_PUSH,&p1);
99
125
if(pDest->type->iType == VT_FLOAT)
101
// TODO: unimplemented
103
// m_str << "pop dword [v_" << pDest->offset << "]" << std::endl;
104
// m_str << "pop dword [v_" << pDest->offset << "+4]" << std::endl;
127
CInstructionParameter p1;
128
p1.iType = PT_DWORD_VALUE_4;
129
p1.value.iOffset = pDest->offset;
131
WriteInstruction(X86_POP,&p1);
133
p1.iType = PT_DWORD_VALUE;
135
WriteInstruction(X86_POP,&p1);
253
284
void CELFOutput::WriteFloatAddInstruction()
286
WriteFloatArithmeticInstruction(X86_FADDP);
258
289
void CELFOutput::WriteFloatSubInstruction()
291
WriteFloatArithmeticInstruction(X86_FSUBRP);
263
294
void CELFOutput::WriteFloatMulInstruction()
296
WriteFloatArithmeticInstruction(X86_FMULP);
268
299
void CELFOutput::WriteFloatDivInstruction()
301
WriteFloatArithmeticInstruction(X86_FDIVRP);
273
304
void CELFOutput::WriteFloatLessInstruction()
488
519
void CELFOutput::WritePrintFloatInstruction()
521
// This one is easy. Just print it!
523
// Well, first we push the format string.
525
CInstructionParameter p1;
526
p1.iType = PT_STRING;
527
p1.value.pString = "printf_f";
529
WriteInstruction(X86_PUSH,&p1);
531
WriteCallInstruction("printf",12);
493
534
void CELFOutput::WritePrintStringInstruction()
530
570
WriteCallInstruction("scanf",8);
533
void CELFOutput::WriteInputFloatInstruction(CVar *)
573
void CELFOutput::WriteInputFloatInstruction(CVar * pVar)
575
// We should simply have to push the address of the
576
// float onto the stack
578
CInstructionParameter p1;
579
p1.iType = PT_REGISTER;
580
p1.value.iRegister = REGISTER_EAX;
582
CInstructionParameter p2;
583
p2.iType = PT_OFFSET;
584
p2.value.iOffset = pVar->offset;
586
WriteInstruction(X86_LEA,&p1,&p2);
588
WritePushRegisterInstruction(REGISTER_EAX);
590
// Now push the format string
592
p1.iType = PT_STRING;
593
p1.value.pString = "scanf_f";
595
WriteInstruction(X86_PUSH,&p1);
599
WriteCallInstruction("scanf",8);
538
602
void CELFOutput::WriteInputStringInstruction(CVar * pVar)
803
void CELFOutput::WriteFloatArithmeticInstruction(X86_OPCODE op)
805
// The first step here is to pop the two floats
806
// on top of the stack
808
CInstructionParameter p1;
814
// Start by popping the top into our temp. float
816
p1.iType = PT_DWORD_VALUE;
817
p1.value.iOffset = 4;
819
WriteInstruction(X86_POP,&p1);
821
p1.iType = PT_DWORD_VALUE_4;
823
WriteInstruction(X86_POP,&p1);
825
// Now load this onto the FPU stack
829
WriteInstruction(X86_FLD,&p1);
831
// Now repeat those steps a second time
834
// Now we perform the operation
836
p1.iType = PT_ST_VAL;
839
CInstructionParameter p2;
840
p2.iType = PT_ST_VAL;
843
WriteInstruction(op,&p1,&p2);
845
// Now we pop the results off of the FPU stack
848
p1.value.iOffset = 4;
850
WriteInstruction(X86_FSTP,&p1);
852
// Now push it back onto the stack
854
p1.iType = PT_DWORD_VALUE_4;
856
WriteInstruction(X86_PUSH,&p1);
858
p1.iType = PT_DWORD_VALUE;
860
WriteInstruction(X86_PUSH,&p1);
863
void CELFOutput::WriteFloatLogicInstruction(X86_OPCODE)