File: GCLoops.cpp

package info (click to toggle)
fauhdlc 20180504-3.1
  • links: PTS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 3,064 kB
  • sloc: cpp: 23,188; ansic: 6,077; yacc: 3,764; lex: 763; makefile: 605; python: 412; xml: 403; sh: 61
file content (123 lines) | stat: -rw-r--r-- 2,713 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* $Id$ 
 *
 * Generate intermediate code, loop specific parts.
 *
 * Copyright (C) 2008-2009 FAUmachine Team <info@faumachine.org>.
 * This program is free software. You can redistribute it and/or modify it
 * under the terms of the GNU General Public License, either version 2 of
 * the License, or (at your option) any later version. See COPYING.
 */

#include "frontend/visitor/GCLoops.hpp"
#include "intermediate/opcodes/Jmp.hpp"
#include "intermediate/opcodes/Jbe.hpp"
#include "intermediate/opcodes/Jb.hpp"
#include "intermediate/opcodes/Mov.hpp"
#include "intermediate/opcodes/Add.hpp"
#include "intermediate/opcodes/Sub.hpp"
#include "intermediate/operands/ImmediateOperand.hpp"
#include "intermediate/operands/RegisterFactory.hpp"
#include "intermediate/container/LabelFactory.hpp"

namespace ast {

using namespace intermediate;

/*
 * ===================== WHILE ITERATE ========================
 */
WhileIterate::WhileIterate(
	CodeContainer &container
) :  		cc(container),
		loopInc(LabelFactory::getLabel("while_iter_inc")),
		loopDone(LabelFactory::getLabel("while_iter_done")),
		loopCheck(LabelFactory::getLabel("while_iter_check"))
{
}

WhileIterate::~WhileIterate()
{
}

void
WhileIterate::addIteration(void)
{
	this->genIterateCode();
}

void
WhileIterate::genIterateCode(void)
{
	this->initializeCounter();

	this->cc.addCode(loopCheck);
	this->checkCondition();

	this->loopBody();

	this->cc.addCode(loopInc);
	this->incCounter();

	Jmp *jmp = new Jmp(this->loopCheck);
	this->cc.addCode(jmp);
	this->cc.addCode(loopDone);
}

/*
 * ===================== FOR LOOP ITERATE =====================
 */
void
ForLoopIterate::initializeCounter(void)
{

	Mov *mov = new Mov(&this->init, &this->cnt);
	this->cc.addCode(mov);
}

void
ForLoopIterate::checkCondition(void)
{
	// FIXME this won't work if rbound is equal to one of the bounds
	//       of the underlying integer type (endless loop).
	//
	// The following construct would be one possible solution:
	//
	// counter = init;
	// if (init > bound) goto out;
	// while (true) {
	// 	loopBody();
	// 	if init == bound goto out;
	// 	loopInc();
	// }
	// out:


	Node *goOut;
	if (this->isAsc) {
		goOut = new Jb(&this->rbound, &this->cnt, this->loopDone);
	} else {
		goOut = new Jb(&this->cnt, &this->rbound, this->loopDone);
	}
	this->cc.addCode(goOut);
}

void
ForLoopIterate::incCounter(void)
{

	Register *tmp = this->cc.createRegister(OP_TYPE_INTEGER);

	Node *inc;
	if (this->isAsc) {
		inc = new Add(&this->cnt, ImmediateOperand::getOne(), tmp);
	} else {
		inc = new Sub(&this->cnt, ImmediateOperand::getOne(), tmp);
	}

	Mov *mov = new Mov(tmp, &this->cnt);

	this->cc.addCode(inc);
	this->cc.addCode(mov);
}

}; /* namespace ast */