1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 /*
21
22 Primitives for some bit operations.
23
24 */
25
26 #include "PyrPrimitive.h"
27 #include "VMGlobals.h"
28 #include "clz.h"
29
30
31 int prNumBits(VMGlobals* g, int numArgsPushed);
prNumBits(VMGlobals * g,int numArgsPushed)32 int prNumBits(VMGlobals* g, int numArgsPushed) {
33 PyrSlot* a = g->sp;
34 SetRaw(a, NUMBITS(slotRawInt(a)));
35 return errNone;
36 }
37
38 int prLog2Ceil(VMGlobals* g, int numArgsPushed);
prLog2Ceil(VMGlobals * g,int numArgsPushed)39 int prLog2Ceil(VMGlobals* g, int numArgsPushed) {
40 PyrSlot* a = g->sp;
41 SetRaw(a, LOG2CEIL(slotRawInt(a)));
42 return errNone;
43 }
44
45 int prCLZ(VMGlobals* g, int numArgsPushed);
prCLZ(VMGlobals * g,int numArgsPushed)46 int prCLZ(VMGlobals* g, int numArgsPushed) {
47 PyrSlot* a = g->sp;
48 SetRaw(a, CLZ(slotRawInt(a)));
49 return errNone;
50 }
51
52 int prCTZ(VMGlobals* g, int numArgsPushed);
prCTZ(VMGlobals * g,int numArgsPushed)53 int prCTZ(VMGlobals* g, int numArgsPushed) {
54 PyrSlot* a = g->sp;
55 SetRaw(a, CTZ(slotRawInt(a)));
56 return errNone;
57 }
58
59 int prNextPowerOfTwo(VMGlobals* g, int numArgsPushed);
prNextPowerOfTwo(VMGlobals * g,int numArgsPushed)60 int prNextPowerOfTwo(VMGlobals* g, int numArgsPushed) {
61 PyrSlot* a;
62
63 a = g->sp;
64
65 SetRaw(a, NEXTPOWEROFTWO(slotRawInt(a)));
66 return errNone;
67 }
68
69 int prIsPowerOfTwo(VMGlobals* g, int numArgsPushed);
prIsPowerOfTwo(VMGlobals * g,int numArgsPushed)70 int prIsPowerOfTwo(VMGlobals* g, int numArgsPushed) {
71 PyrSlot* a = g->sp;
72 SetBool(a, ISPOWEROFTWO(slotRawInt(a)));
73 return errNone;
74 }
75
76 int prBinaryGrayCode(VMGlobals* g, int numArgsPushed);
prBinaryGrayCode(VMGlobals * g,int numArgsPushed)77 int prBinaryGrayCode(VMGlobals* g, int numArgsPushed) {
78 PyrSlot* a;
79
80 a = g->sp;
81 SetRaw(a, GRAYCODE(slotRawInt(a)));
82 return errNone;
83 }
84
85 int prSetBit(VMGlobals* g, int numArgsPushed);
prSetBit(VMGlobals * g,int numArgsPushed)86 int prSetBit(VMGlobals* g, int numArgsPushed) {
87 PyrSlot* a = g->sp - 2;
88 PyrSlot* b = g->sp - 1;
89 PyrSlot* c = g->sp;
90
91 int32 bit, mask;
92 int err = slotIntVal(b, &bit);
93 if (err)
94 return err;
95 bit = bit & 31;
96 mask = 1L << bit;
97 if (IsFalse(c)) {
98 SetRaw(a, slotRawInt(a) & ~mask);
99 } else {
100 SetRaw(a, slotRawInt(a) | mask);
101 }
102 return errNone;
103 }
104
105 int prHammingDistance(VMGlobals* g, int numArgsPushed);
prHammingDistance(VMGlobals * g,int numArgsPushed)106 int prHammingDistance(VMGlobals* g, int numArgsPushed) {
107 PyrSlot* a = g->sp - 1;
108 PyrSlot* b = g->sp;
109
110 if (NotInt(a) || NotInt(b))
111 return errWrongType;
112
113 int aInt = slotRawInt(a);
114 int bInt = slotRawInt(b);
115
116 int count = 0, mask = 1;
117 for (int i = 0; i < 32; i++) {
118 if ((aInt & mask) != (bInt & mask))
119 count = count + 1;
120 mask = mask << 1;
121 }
122 SetRaw(a, count);
123
124 return errNone;
125 }
126
127 void initBitPrimitives();
initBitPrimitives()128 void initBitPrimitives() {
129 int base, index = 0;
130
131 base = nextPrimitiveIndex();
132
133 definePrimitive(base, index++, "_NextPowerOfTwo", prNextPowerOfTwo, 1, 0);
134 definePrimitive(base, index++, "_IsPowerOfTwo", prIsPowerOfTwo, 1, 0);
135 definePrimitive(base, index++, "_CLZ", prCLZ, 1, 0);
136 definePrimitive(base, index++, "_CTZ", prCTZ, 1, 0);
137 definePrimitive(base, index++, "_NumBits", prNumBits, 1, 0);
138 definePrimitive(base, index++, "_Log2Ceil", prLog2Ceil, 1, 0);
139 definePrimitive(base, index++, "_SetBit", prSetBit, 3, 0);
140 definePrimitive(base, index++, "_BinaryGrayCode", prBinaryGrayCode, 1, 0);
141 definePrimitive(base, index++, "_HammingDistance", prHammingDistance, 2, 0);
142 }
143
144
145 #if _SC_PLUGINS_
146
147 # include "SCPlugin.h"
148
149 // export the function that SC will call to load the plug in.
150 # pragma export on
151 extern "C" {
152 SCPlugIn* loadPlugIn(void);
153 }
154 # pragma export off
155
156
157 // define plug in object
158 class APlugIn : public SCPlugIn {
159 public:
160 APlugIn();
161 virtual ~APlugIn();
162
163 virtual void AboutToCompile();
164 };
165
APlugIn()166 APlugIn::APlugIn() {
167 // constructor for plug in
168 }
169
~APlugIn()170 APlugIn::~APlugIn() {
171 // destructor for plug in
172 }
173
AboutToCompile()174 void APlugIn::AboutToCompile() {
175 // this is called each time the class library is compiled.
176 initBitPrimitives();
177 }
178
179 // This function is called when the plug in is loaded into SC.
180 // It returns an instance of APlugIn.
loadPlugIn()181 SCPlugIn* loadPlugIn() { return new APlugIn(); }
182
183 #endif
184